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

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

События ядра

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

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

kernel.request

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

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

Простите больше о событии 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(FilterControllerEvent $event)
{
    // ...

    // the controller can be changed to any PHP callable
    $event->setController($myCustomController);
}
Прочтите больше о событии kernel.controller.

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

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

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(GetResponseForControllerResultEvent $event)
{
    $val = $event->getControllerResult();
    $response = new Response();

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

    $event->setResponse($response);
}
Прочтите больще о событии kernel.view.

kernel.response

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

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

1
2
3
4
5
6
public function onKernelResponse(FilterResponseEvent $event)
{
    $response = $event->getResponse();

    // ... изменить объект ответа
}
Прочтите больще о событии kernel.response.

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

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

kernel.finish_request

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

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

1
2
3
4
5
6
7
8
9
public function onKernelFinishRequest(FinishRequestEvent $event)
{
    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). Оно полезно для выполнения медленных или сложных задач, которые не должны быть выполнены для отправки ответа (например, отправка писем).

Прочтите больше о событии 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\HttpKernel\Event\GetResponseForExceptionEvent;
use Symfony\Component\HttpFoundation\Response;

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

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

Note

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

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

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

Note

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

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

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

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

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

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

Эта документация является переводом официальной документации Symfony и предоставляется по свободной лицензии CC BY-SA 3.0.