Встроенные события Symfony

Дата обновления перевода 2023-09-25

Встроенные события Symfony

Фреймворк Symfony - это фреймворк HTTP Запрос-Ответ. Во время обработки HTTP запроса, фреймворк Symfony (или любого приложения, использующего компонент HttpKernel) запускает какие-то события, которые вы можете использовать, чтобы изменять то, как обрабатывается запрос.

События ядра

Каждое событие, выполненное компонентом HttpKernel - это подкласс KernelEvent, который предоставляет следующую информацию:

getRequestType()
Возвращает тип запроса (HttpKernelInterface::MAIN_REQUEST или HttpKernelInterface::SUB_REQUEST).
getKernel()
Возвращает Ядро, обрабатывающее запрос.
getRequest()
Возвращает текущий обрабатываемый Request.
isMainRequest()
Проверяет, есть ли основной запрос.

kernel.request

Класс события: GetResponseEvent

Это событие диспетчеризируется Symfony очень рано, до определения контроллера. Полезен для добавления информации к Запросу или возвращения Ответа раньше, чтобы остановить обработку запроса.

See also

Прочтите больше о событии kernel.request .

Выполните эту команду, чтобы узнать, какие слушатели зарегистрированы для этого события и их приоритетность:

1
$ php bin/console debug:event-dispatcher kernel.request

kernel.controller

Класс события: FilterControllerEvent

Это событие запсукается после того, как выплняемый контроллер был разрешён, но до того, как он был выполнен. Полезно для инициализации вещей, необходимых позже контроллеру, вроде преобразователей param, и даже для изменения контроллера полностью:

1
2
3
4
5
6
7
8
9
use Symfony\Component\HttpKernel\Event\FilterControllerEvent;

public function onKernelController(ControllerEvent $event): void
{
    // ...

    // the controller can be changed to any PHP callable
    $event->setController($myCustomController);
}

See also

Прочтите больше о событии kernel.controller .

Выполните эту команду, чтобы узнать, какие слушатели зарегистрированы для этого события и их приоритетность:

1
$ php bin/console debug:event-dispatcher kernel.controller

kernel.controller_arguments

Класс события: ControllerArgumentsEvent

Это событие запускается прямо перед вызовом контроллера. Оно полезно для конфигурации аргументов, которые будут переданы контроллеру. Обычно, оно используется для отображения параметров маршрутизации URL в соотвтетствующих проименованных аргументах; или для передачи запроса, когда находится подсказка Request:

1
2
3
4
5
6
7
8
9
10
11
12
13
use Symfony\Component\HttpKernel\Event\ControllerArgumentsEvent;

public function onKernelControllerArguments(ControllerArgumentsEvent $event): void
{
    // ...

    // получить аргументы контроллера и запроса
    $namedArguments = $event->getRequest()->attributes->all();
    $controllerArguments = $event->getArguments();

    // установить аргументы контроллера и изменить изначальные аргументы или добавить новые
    $event->setArguments($newArguments);
}

Выполните эту команду, чтобы узнать, какие слушатели зарегистрированы для этого события, и их приоритеты:

1
$ php bin/console debug:event-dispatcher kernel.controller_arguments

kernel.view

Класс события: GetResponseForControllerResultEvent

Это событие запускается после того, как контроллер был выполнен, но только, если контроллер не возвращает объект Response. Полезно для преобразования возвращённого значения (например, строки с некоторым HTML содержанием) в объект Response, необходимый Symfony:

1
2
3
4
5
6
7
8
9
10
11
12
use Symfony\Component\HttpKernel\Event\GetResponseForControllerResultEvent;
use Symfony\Component\HttpFoundation\Response;

public function onKernelView(ViewEvent $event): void
{
    $val = $event->getControllerResult();
    $response = new Response();

    // ... как-то настроить Ответ из возвратного значения

    $event->setResponse($response);
}

See also

Прочтите больше о событии kernel.view .

Выполните эту команду, чтобы узнать, какие слушатели зарегистрированы для этого события, и их приоритеты:

1
$ php bin/console debug:event-dispatcher kernel.view

kernel.response

Класс события: FilterResponseEvent

Это событие запускается после того, как контроллер или любой слушатель kernel.view возвращает объект Response. Полезно для изменения или замены ответа до его отправки обратно (например, добавлять / изменять HTTP заголовки, добавлять cookie и т.д.):

1
2
3
4
5
6
7
8
use Symfony\Component\HttpKernel\Event\ResponseEvent;

public function onKernelResponse(ResponseEvent $event): void
{
    $response = $event->getResponse();

    // ... изменить объект ответа
}

See also

Прочтите больще о событии kernel.response .

Выполните эту команду, чтобы узнать, какие слушатели зарегистрированы для этого события и их приоритетность:

1
$ php bin/console debug:event-dispatcher kernel.response

kernel.finish_request

Класс события: FinishRequestEvent

Это событие выполняется после события kernel.response. Оно полезно для сброса глобального состояния приложения (например, слушатель переводчика сбрасывает локаль переводчика по одному из родительских запросов):

1
2
3
4
5
6
7
8
9
10
11
use Symfony\Component\HttpKernel\Event\FinishRequestEvent;

public function onKernelFinishRequest(FinishRequestEvent $event): void
{
    if (null === $parentRequest = $this->requestStack->getParentRequest()) {
        return;
    }

    // сбросить локаль подзапроса в локаль родительского запроса
    $this->setLocale($parentRequest);
}

Выполните эту команду, чтобы узнать, какие слушатели зарегистрированы для этого события и их приоритетность:

1
$ php bin/console debug:event-dispatcher kernel.finish_request

kernel.terminate

Класс события: PostResponseEvent

Это событие выполняется после того, как был отправлен ответ (после выполнения метода handle() method). Оно полезно для выполнения медленных или сложных задач, которые не должны быть выполнены для отправки ответа (например, отправка писем).

See also

Прочтите больше о событии kernel.terminate .

Выполните эту команду, чтобы узнать, какие слушатели зарегистрированы для этого события и их приоритетность:

1
$ php bin/console debug:event-dispatcher kernel.terminate

kernel.exception

Класс события: GetResponseForExceptionEvent

Это событие выполняется как только вознкает ошибка во время обработки HTTP запроса. Оно полезно для восстановления после ошибо или изменения деталей исключений, отправленных в качестве ответа:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\ExceptionEvent;

public function onKernelException(ExceptionEvent $event): void
{
    $exception = $event->getThrowable();
    $response = new Response();
    // настроейте объект Ответ, основываясь на пойманном исключении
    $event->setResponse($response);

    // вы можете, как вариант, установить новое Исключение
    // $exception = new \Exception('Some special exception');
    // $event->setThrowable($exception);
}

Note

TwigBundle регистрирует ExceptionListener, который пересылает Request заданному контроллеру, определённому параметром exception_listener.controller.

Symfony использует следующую логику для определения HTTP статус-кода ответа:

  • Если isClientError(), isServerError() или isRedirect() - true, то в вашем объекте Response используется статус-код;
  • Если исходное исключение реализует HttpExceptionInterface, то в исключении вызывается и используется getStatusCode() (также добавляются заголовки из getHeaders());
  • Если не совпадает ничего из вышеперечисленного, то используется статус-код 500.

Note

Если вы хотите перезаписать статус-код ответа исключения, что не стоит делать без весомой причины, вначале вызовите ExceptionEvent::allowCustomResponseCode(), а потом установите статус-код в ответе:

1
2
3
$event->allowSuccessfulResponse();
$response = new Response('No Content', 204);
$event->setResponse($response);

Статус-код, отправленный клиенту в примере выше, будет 204. Если опустить $event->allowSuccessfulResponse(), тогда ядро установит необходимый статус-код, основываясь на типе вызванного исключения.

See also

Прочтите больше о событии kernel.exception .

Выполните эту команду, чтобы узнать, какие слушатели зарегистрированы для этого события и их приоритетность:

1
$ php bin/console debug:event-dispatcher kernel.exception