Ответ
Ядро Symfony (HttpKernel) генерирует ряд событий на протяжении жизненного цикла обработки HTTP-запроса. Эти события позволяют внедрять кастомную логику на разных этапах. Основные события определены в классе SymfonyComponentHttpKernelKernelEvents.
Полный список основных событий ядра:
-
KernelEvents::REQUEST(kernel.request):- Когда: Сразу после получения
Requestот фронт-контроллера (index.php), но до определения роута и контроллера. - Зачем: Для глобальной инициализации, локализации, ранней проверки прав доступа (например, брандмауэр безопасности слушает это событие).
- Когда: Сразу после получения
-
KernelEvents::CONTROLLER(kernel.controller):- Когда: После определения контроллера и аргументов, но непосредственно перед его вызовом.
- Зачем: Для модификации контроллера (например, подмена на другой) или его аргументов (например, десериализация тела запроса в объект).
-
KernelEvents::CONTROLLER_ARGUMENTS(kernel.controller_arguments):- Когда: После разрешения всех аргументов контроллера, но перед вызовом.
- Зачем: Для последней проверки или модификации массива аргументов.
-
KernelEvents::VIEW(kernel.view):- Когда: Если контроллер вернул значение, которое не является объектом
Response. - Зачем: Чтобы преобразовать результат контроллера (массив, объект) в
Response. За это отвечает, например,SymfonyBundleFrameworkBundleControllerAbstractController.
- Когда: Если контроллер вернул значение, которое не является объектом
-
KernelEvents::RESPONSE(kernel.response):- Когда: После того как у ядра есть объект
Response(полученный от контроллера или сформированный вVIEW), но перед его отправкой. - Зачем: Для модификации ответа — добавление заголовков, сжатие GZIP, инъекция контента.
- Когда: После того как у ядра есть объект
-
KernelEvents::FINISH_REQUEST(kernel.finish_request):- Когда: Сразу после
RESPONSE, когда основной запрос завершен. Используется для очистки контекстозависимых данных (например, локали вRequestContext).
- Когда: Сразу после
-
KernelEvents::TERMINATE(kernel.terminate):- Когда: После отправки ответа клиенту (соединение закрыто).
- Зачем: Для выполнения задач, которые не должны задерживать отправку ответа: тяжелое логирование, отправка email, обработка очередей.
-
KernelEvents::EXCEPTION(kernel.exception):- Когда: При возникновении любого необработанного исключения в процессе работы ядра.
- Зачем: Для кастомной обработки ошибок — преобразование исключения в пользовательскую страницу ошибки, логирование, отправку уведомлений.
Пример слушателя для логирования исключений:
# config/services.yaml
services:
AppEventListenerExceptionLoggerListener:
tags:
- { name: kernel.event_listener, event: kernel.exception, priority: 100 }
// src/EventListener/ExceptionLoggerListener.php
use PsrLogLoggerInterface;
use SymfonyComponentHttpKernelEventExceptionEvent;
class ExceptionLoggerListener
{
public function __construct(private LoggerInterface $logger) {}
public function onKernelException(ExceptionEvent $event): void
{
$exception = $event->getThrowable();
$this->logger->error('Unhandled exception', [
'exception' => $exception,
'url' => $event->getRequest()->getUri(),
]);
// Можно НЕ останавливать распространение события,
// чтобы стандартный обработчик ошибок Symfony тоже сработал.
}
}