如何在接收事件的多个 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) 调度程序
如何在 Lumen 6x 中实现默认 Laravel 重置密码