Перейти к содержанию

Подключить через PSR-14

Сторонняя библиотека или старый код знают только стандартный Psr\EventDispatcher\EventDispatcherInterface. Переписывать их под роутер незачем: Psr14EventDispatcher — тот же роутер под стандартным интерфейсом.

use Psr\EventDispatcher\EventDispatcherInterface;
use Selyusize\EventsRouter\EventRouterFactory;
use Selyusize\EventsRouter\Psr14\Psr14EventDispatcher;

$events = EventRouterFactory::create();
$events->listen('shop.order.{order_id}.paid', SendReceipt::class);

$dispatcher = new Psr14EventDispatcher(
    $events,
    static fn (object $event): string => match (true) {
        $event instanceof OrderPaid => 'shop.order.' . $event->orderId . '.paid',
    },
);

// Дальше код знает только о PSR-14
function pay(EventDispatcherInterface $dispatcher): void
{
    $dispatcher->dispatch(new OrderPaid(42, 1500));
}

pay($dispatcher);
Чек по заказу 42 на 1500 ₽

Как объект становится событием

Что передали в dispatch() Что получает роутер
объект, реализующий EventInterface (например, Event) его же, как есть
любой другой объект new Event(маппер($object), $object): имя даёт маппер из конструктора, сам объект становится payload
любой другой объект, а маппера нет исключение UnmappableEvent

Имя события по имени класса не угадывается. Правило задаёте вы, явно, в одном месте.

Что гарантирует адаптер

  • dispatch() возвращает тот же объект, что получил, как требует PSR-14.
  • Если объект реализует StoppableEventInterface, слушатель может остановить рассылку.
  • Ошибки слушателей обрабатываются так же, как в EventRouter::dispatch(): тот же обработчик, та же стратегия, тот же лог.

Отчёт о рассылке PSR-14 не возвращает. Если он нужен, вызывайте роутер напрямую.