#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. Это, безусловно, наименее сложный подход для решения моих потребностей. Спасибо за это, иногда слишком легко забыть основы, например, добавить параметр.