Как устроен Event Dispatcher в Symfony?

«Как устроен Event Dispatcher в Symfony?» — вопрос из категории Symfony, который задают на 24% собеседований PHP Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Event Dispatcher в Symfony реализует паттерн "Наблюдатель" (Observer) и служит центральным механизмом для организации слабосвязанной коммуникации между компонентами приложения.

Основные компоненты:

  1. EventDispatcherInterface — центральный сервис, управляющий подпиской слушателей и рассылкой событий.
  2. Объект события — любой PHP-объект, несущий контекст и данные о произошедшем. Часто расширяет базовый класс SymfonyContractsEventDispatcherEvent.
  3. Слушатели (Listeners) — вызываемые объекты (функции, инвайтабл-классы), которые реагируют на конкретное событие.
  4. Подписчики (Subscribers) — классы, реализующие EventSubscriberInterface, которые централизованно объявляют, на какие события они подписаны.

Пример диспатча события:

// 1. Создаем объект события
$orderEvent = new OrderPlacedEvent($order);

// 2. Диспатчим его через центральный сервис
/** @var SymfonyContractsEventDispatcherEventDispatcherInterface $dispatcher */
$dispatcher->dispatch($orderEvent, OrderPlacedEvent::NAME);

Пример слушателя (Listener):

// Сервис, зарегистрированный как слушатель в конфигурации (services.yaml)
#[AsEventListener(event: OrderPlacedEvent::NAME)]
class SendOrderConfirmationListener
{
    public function __invoke(OrderPlacedEvent $event): void
    {
        $order = $event->getOrder();
        // Отправляем email подтверждения...
    }
}

Ключевые особенности:

  • Приоритеты: Слушателям можно задавать числовой приоритет (чем выше число, тем раньше выполнение).
  • Остановка распространения: Вызов $event->stopPropagation() предотвращает вызов последующих слушателей.
  • Встроенные события Symfony: Фреймворк активно использует эту систему (например, события жизненного цикла ядра kernel.request, kernel.response, события консоли, безопасности).
  • Гибкость: Event Dispatcher лежит в основе многих компонентов Symfony (Form, Security, Workflow), позволяя легко расширять их поведение без модификации ядра.