如何在接收事件的多个 Laravel/Lumen 侦听器中保留模型状态?

Posted

技术标签:

【中文标题】如何在接收事件的多个 Laravel/Lumen 侦听器中保留模型状态?【英文标题】:How can I preserve model state across multiple Laravel/Lumen listeners that receive an event? 【发布时间】:2022-01-07 13:05:07 【问题描述】:

使用 Lumen 5.5、PHP 7.3

我的目标是在保持代码简洁的同时扩展模型上的现有功能。使用事件/侦听器模式是有道理的,但我遇到了一些设计问题,我需要在侦听器中访问模型的原始状态。该状态似乎不可访问。

它是如何开始的:模型上的这个方法(为公众查看而清理)通过将 null 分配给某些属性来“重置”它。这个没问题。

    public function reset()
    
        $this->association_id = null;
        $this->associated_at = null;
        $this->save();
    

进展如何:添加了一个事件调度,以便我可以向侦听器添加新功能。

    public function reset()
    
        $this->association_id = null;
        $this->associated_at = null;
        $this->save();

        event(new ResetEvent($this));
    

事件

class ResetEvent

    public $myModel;

    public function __construct($myModel)
    
        $this->myModel = $myModel;
    

听众

class ResetListener

    public function handle(ResetEvent $event)
    
        $association_id = $event->myModel->association_id;
        // OR...
        $association_id = $event->myModel->getOriginal('association_id');

        // Do new functionality...
    

挑战

侦听器需要访问模型中的association_id 值。不幸的是,在从模型的 reset 方法调用 save() 方法后,这不再可用。我确实尝试在侦听器的模型上使用getOriginal() 方法,但那里的值也为空。感觉应该可以了。

请注意,此实现使用同步事件;不涉及外部异步排队系统。

选项

一种选择是将意图和名称从ResetEvent 更改为ResetRequestEvent,并使用一个侦听器对模型执行属性修改,并使用另一个侦听器执行我添加的新功能。如果模型通过引用传递给侦听器,这可能会也可能不会导致竞争条件。

另一个选项可能是我还没有学会的一种方法,可以在模型传递给事件时保留模型的状态。想到 Java 风格的数据传输对象,但这听起来像是在躲避框架提供的奢侈品。

寻找进一步推进任一选项的想法。

【问题讨论】:

【参考方案1】:

您可以将其他参数传递给您的事件。例如:

 public function reset()
 
    $lastAssociation = $this->association_id;
    $this->association_id = null;
    $this->associated_at = null;
    $this->save();

    event(new ResetEvent($this, $lastAssociation));
 

然后您的活动将是:

class ResetEvent

    public $myModel;
    public $lastAssociationId;

    public function __construct($myModel, $lastAssociationId)
    
        $this->myModel = $myModel;
        $this->lastAssociationId = $lastAssociationId;
    

最后一个关联将在您的听众中以$event->lastAssociationId 的形式出现,希望对您有所帮助。

【讨论】:

这绝对是解决我需求的最简单的方法。感谢您,有时很容易忘记基础知识,例如添加参数。

以上是关于如何在接收事件的多个 Laravel/Lumen 侦听器中保留模型状态?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Docker 上运行 Laravel (Lumen) 调度程序

Laravel/流明 |未能分发事件

如何在 Lumen 6x 中实现默认 Laravel 重置密码

如何在 Laravel/Lumen 中捕获 401 响应?

如何在 Laravel Lumen 8 中设置响应的 cookie

在 Laravel/Lumen 中动态创建的工作守护进程队列