Size: a a a

2020 October 15

В

Виктор in Yii Framework 3
В общем, да, если не возвращать событие из диспетчера, будет чуть лучше. Но все равно можно все поломать подписчиком, принимающим событие по ссылке)
источник

В

Виктор in Yii Framework 3
Я вот PR с тестом подготовил, чтобы такого больше нельзя было сделать: https://github.com/yiisoft/event-dispatcher/pull/41
источник

В

Виктор in Yii Framework 3
Сергей Предводителев
final class Dispatcher implements EventDispatcherInterface
{
   private ListenerProviderInterface $listenerProvider;

   public function __construct(ListenerProviderInterface $listenerProvider)
   {
       $this->listenerProvider = $listenerProvider;
   }

   public function dispatch(object $event): object
   {
       foreach ($this->listenerProvider->getListenersForEvent($event) as $listener) {
     $listener(clone $event);
       }
       return $event;
   }
}
тоже вариант. Я решил вопрос замыканием.
источник

В

Виктор in Yii Framework 3
Один нюанс есть: в эвенте может быть определен метод __clone, который такое клонирование поломает.
источник

СП

Сергей Предводителев... in Yii Framework 3
А как это работает, можешь пояснить?
Ты передаёшь $event в метод, который посылает его в слушателя. Почему замены не происходит? Объекты ведь по ссылке передаются
источник

В

Виктор in Yii Framework 3
Сергей Предводителев
А как это работает, можешь пояснить?
Ты передаёшь $event в метод, который посылает его в слушателя. Почему замены не происходит? Объекты ведь по ссылке передаются
Передача объекта по значению и по ссылке работают по-разному. Тут кто-то ссылку кидал с описанием, но я сейчас навряд ли найду
источник

СП

Сергей Предводителев... in Yii Framework 3
по-умолчанию ведь по ссылке же
источник

В

Виктор in Yii Framework 3
Сергей Предводителев
по-умолчанию ведь по ссылке же
путаница в понятиях потому что
источник

AB

Alexander Borisov in Yii Framework 3
А может правильней проверять был ли объект изменен и если да, то кидать исключение?
источник

В

Виктор in Yii Framework 3
Когда передаешь объект по значению, ты можешь менять его состояние, но не можешь перезаписать ячейку в памяти, где этот объект хранится. А когда передаешь по ссылке (с &), ты имеешь дело со ссылкой на ячейку памяти, и меняешь ее, а не сам объект.
источник

В

Виктор in Yii Framework 3
Alexander Borisov
А может правильней проверять был ли объект изменен и если да, то кидать исключение?
сильно медленнее станет диспетчер: во-первых, тебе надо будет как-то хранить эталонный вариант события, во-вторых, тратить процессор на их сравнение, и в третьих - как-то работать с изменяемыми событиями (StoppableEvent, например). И все это - в цикле.
источник

AB

Alexander Borisov in Yii Framework 3
Виктор
сильно медленнее станет диспетчер: во-первых, тебе надо будет как-то хранить эталонный вариант события, во-вторых, тратить процессор на их сравнение, и в третьих - как-то работать с изменяемыми событиями (StoppableEvent, например). И все это - в цикле.
public function dispatch(object $event): object
{
   $id = spl_object_id($event);
   foreach ($this->listenerProvider->getListenersForEvent($event) as $listener) {
       $listener($event);
   }
   
   if ($id !== spl_object_id($event)) {
       throw new \LogicException();
   }
   
   return $event;
}
источник

AB

Alexander Borisov in Yii Framework 3
ну «сильно медленнее», это громко 🙂
источник

В

Виктор in Yii Framework 3
Виктор
fn (&$event) => $event = new AnotherEvent();
@BoShurik, а в этом кейсе spl_object_id норм сработает? Исходный объект ведь уничтожен, получается. Хотя, если через замыкание... То тогда смысл теряется, разве что исключение ради исключения кидать. Вообще, spl_object_id никогда не использовал.
источник

AB

Alexander Borisov in Yii Framework 3
Виктор
@BoShurik, а в этом кейсе spl_object_id норм сработает? Исходный объект ведь уничтожен, получается. Хотя, если через замыкание... То тогда смысл теряется, разве что исключение ради исключения кидать. Вообще, spl_object_id никогда не использовал.
не вижу проблем. мы сначала сохранили id, новый объект будет с другим id
источник

В

Виктор in Yii Framework 3
Alexander Borisov
не вижу проблем. мы сначала сохранили id, новый объект будет с другим id
не обязательно
источник

В

Виктор in Yii Framework 3
согласно документации, id может быть переиспользован, если объект, которому он назначен, уничтожен
источник

СП

Сергей Предводителев... in Yii Framework 3
Виктор
Когда передаешь объект по значению, ты можешь менять его состояние, но не можешь перезаписать ячейку в памяти, где этот объект хранится. А когда передаешь по ссылке (с &), ты имеешь дело со ссылкой на ячейку памяти, и меняешь ее, а не сам объект.
Правильно я понял?
источник

В

Виктор in Yii Framework 3
Сергей Предводителев
Правильно я понял?
да
источник

СП

Сергей Предводителев... in Yii Framework 3
👍
Убережёт от недобросовестных подписчиков :)
источник