Как я могу сохранить состояние модели для нескольких прослушивателей Laravel/Lumen, которые получают событие?

#php #laravel #lumen #passive-event-listeners

#php #ларавель #просвет #пассивные слушатели событий

Вопрос:

Использование Lumen 5.5, PHP 7.3

Моя цель-расширить существующую функциональность модели, сохраняя при этом чистоту кода. Использование шаблона Событие/Прослушиватель имело смысл, но я сталкиваюсь с некоторыми проблемами проектирования, когда мне нужен доступ к исходному состоянию модели в прослушивателе. Это состояние, по-видимому, недоступно.

Как это началось: этот метод на модели (очищенной для публичного просмотра) «сбрасывает» ее, присваивая null некоторым атрибутам. С этим проблем нет.

 public function reset()  {  $this-gt;association_id = null;  $this-gt;associated_at = null;  $this-gt;save();  }  

Как это происходит: Добавлена отправка событий, чтобы я мог добавить новые функции для слушателей.

 public function reset()  {  $this-gt;association_id = null;  $this-gt;associated_at = null;  $this-gt;save();   event(new ResetEvent($this));  }  

Событие

 class ResetEvent {  public $myModel;   public function __construct($myModel)  {  $this-gt;myModel = $myModel;  } }  

Слушатель

 class ResetListener {  public function handle(ResetEvent $event)  {  $association_id = $event-gt;myModel-gt;association_id;  // OR...  $association_id = $event-gt;myModel-gt;getOriginal('association_id');   // Do new functionality...  } }  

вызов

Слушателю необходим доступ к association_id значению из модели. К сожалению, это больше недоступно после save() вызова метода из метода сброса модели. Я попытался использовать getOriginal() метод на модели из прослушивателя, но там также было значение null. Такое чувство, что это должно было сработать.

Обратите внимание, что в этой реализации используются синхронные события; не задействована внешняя асинхронная система массового обслуживания.

Опции

Один из вариантов-изменить намерение и имя с ResetEvent на а ResetRequestEvent и использовать одного слушателя для изменения атрибута модели, а другой-для выполнения новой функции, которую я добавляю. Это может привести или не привести к условиям гонки, если модель передается слушателям по ссылке.

Другим вариантом может быть способ, которому я еще не научился, чтобы сохранить состояние модели по мере ее передачи событию. На ум приходят объекты передачи данных в стиле Java, но это звучит как уклонение от роскоши, предоставляемой фреймворком.

Ищу идеи для дальнейшего развития любого из вариантов.

Ответ №1:

Вы можете передать дополнительные параметры для вашего мероприятия. Например:

 public function reset()  {  $lastAssociation = $this-gt;association_id;  $this-gt;association_id = null;  $this-gt;associated_at = null;  $this-gt;save();   event(new ResetEvent($this, $lastAssociation));  }  

и тогда ваше мероприятие будет:

 class ResetEvent {  public $myModel;  public $lastAssociationId;   public function __construct($myModel, $lastAssociationId)  {  $this-gt;myModel = $myModel;  $this-gt;lastAssociationId = $lastAssociationId;  } }  

Последняя ассоциация будет доступна в вашем слушателе , как $event-gt;lastAssociationId , надеюсь, это поможет.

Комментарии:

1. Это, безусловно, наименее сложный подход для решения моих потребностей. Спасибо за это, иногда слишком легко забыть основы, например, добавить параметр.