Ответ
Концепция Event Dispatcher (диспетчера событий) является паттерном, и конкретные события зависят от фреймворка или приложения. В контексте Symfony (как эталонной реализации для PHP) можно выделить несколько категорий встроенных событий:
1. События Ядра (HttpKernel): Обрамляют жизненный цикл HTTP-запроса.
KernelEvents::REQUEST(kernel.request): Вызывается в самом начале запроса. Используется для инициализации, проверки прав доступа глобально.KernelEvents::CONTROLLER(kernel.controller): Вызывается непосредственно перед вызовом контроллера. Позволяет изменить контроллер или аргументы (например, для преобразования данных запроса в DTO).KernelEvents::VIEW(kernel.view): Вызывается, если контроллер вернул не объектResponse, а какие-то данные. Позволяет преобразовать эти данные вResponse.KernelEvents::RESPONSE(kernel.response): Вызывается перед отправкой ответа клиенту. Позволяет модифицироватьResponse(добавить заголовки, сжать контент).KernelEvents::FINISH_REQUEST(kernel.finish_request): Вызывается после создания ответа, когда основной запрос обработан.KernelEvents::TERMINATE(kernel.terminate): Вызывается после отправки ответа клиенту. Идеально для «тяжелых» фоновых задач (логирование, отправка email), чтобы не задерживать ответ.KernelEvents::EXCEPTION(kernel.exception): Вызывается при возникновении необработанного исключения. Используется для кастомной обработки ошибок.
2. События Консоли (Console): Аналогичны событиям ядра, но для CLI-команд.
ConsoleEvents::COMMAND,ConsoleEvents::TERMINATE,ConsoleEvents::ERROR.
3. События Компонентов: Другие компоненты Symfony генерируют свои события (например, FormEvents, SecurityEvents).
4. Пользовательские события: Разработчик может создавать свои классы событий для бизнес-логики (например, OrderPlacedEvent, UserRegisteredEvent).
Пример подписки в Symfony через атрибуты:
use SymfonyComponentHttpKernelEventResponseEvent;
use SymfonyComponentEventDispatcherAttributeAsEventListener;
#[AsEventListener(event: KernelEvents::RESPONSE)]
class AddSecurityHeadersListener
{
public function __invoke(ResponseEvent $event): void
{
$response = $event->getResponse();
$response->headers->set('X-Content-Type-Options', 'nosniff');
$response->headers->set('X-Frame-Options', 'DENY');
}
}