Вбудовані події Symfony

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

Вбудовані події Symfony

Під час обробки 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
{
    // ...

    // контролер можна змінити на будь-яке PHP-викличне
    $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 заголовки, додавати куки і т.д.):

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