Вероятно, вы знаете о том, что при вызове метода HttpKernel::handle()
вторым параметром идёт аргумент типа запроса — $type
:
public function handle(
Request $request,
$type = HttpKernelInterface::MASTER_REQUEST,
$catch = true
) {
...
}
В интерфейсе HttpKernelInterface
определены две константы, позволяющие определить тип запроса:
HttpKernelInterface::MASTER_REQUEST
— главный запрос (мастер)HttpKernelInterface::SUB_REQUEST
— поздапрос
Для каждого запроса в вашем PHP-приложении первый запрос, который обрабатывается ядром, имеет тип мастер — HttpKernelInterface::MASTER_REQUEST
. Это определено неявно, так как аргумент $type
не указывается во фронт-контроллерах (app.php и app_dev.php):
$response = $kernel->handle($request);
Многие слушатели ожидают события ядра, как это было описано ранее, но включаются в работу лишь тогда, когда запрос имеет тип HttpKernelInterface::MASTER_REQUEST
. Например, Firewall
не будет ничего делать в случае, если запрос имеет тип подзапроса:
public function onKernelRequest(GetResponseEvent $event)
{
if (HttpKernelInterface::MASTER_REQUEST !== $event->getRequestType()) {
return;
}
...
}
Когда используются подзапросы?
Подзапросы используются для изоляции создания объекта ответа. Например, когда исключение перехвачено ядром, стандартный обработчик исключений пытается выполнить назначенный для этого исключения контроллер (см. предыдущую часть Обработка исключений). Для этого создаётся подзапрос:
public function onKernelException(GetResponseForExceptionEvent $event)
{
$request = $event->getRequest();
...
$request = $request->duplicate(null, null, $attributes);
$request->setMethod('GET');
$response = $event
->getKernel()
->handle($request, HttpKernelInterface::SUB_REQUEST, true);
$event->setResponse($response);
}
Также каждый раз, когда вы рендерите контроллер через Twig-шаблон, создаётся и обрабатывается подзапрос:
{{ render(controller('BlogBundle:Post:list')) }}
Когда вы пишете собственный слушатель событий ядра…
Спросите себя, должен ли ваш слушатель реагировать на мастер-запрос, на подзапрос, или же на оба типа. И используйте условие для проверки, которое приведено выше.