嵌入式 Twig 控制器导致 kernel.request 事件多次触发
Embedded Twig controllers cause kernel.request events to fire multiple times
在我的 Symfony 项目中,我遇到了一个关于 kernel.request
event listeners firing multiple times when embedded Twig controllers 的奇怪问题。
在我的自定义事件侦听器中,我有一个事件侦听器,如果存在特定条件(在本例中为过期密码),它会发送重定向响应。为了防止重定向循环,我检查了我们是否已经在页面上:
if ($event->getRequest()->get('_route') != 'user_change_password') {
$response = new RedirectResponse($this->router->generate('user_change_password'));
$event->setResponse($response);
}
但这并没有阻止重定向循环。在我添加日志记录之前,我不知道嵌入式控制器会触发 kernel.request
事件(事后看来很明显,因为这些嵌入式控制器通过发送 "sub-request" 来工作)。我在 base twig 模板中有一个嵌入式控制器,用于检查任何警报消息并显示它们。
鉴于以上,我如何
- 能够将动态内容插入基本模板(所有其他模板扩展),并且
- 没有
kernel.request
事件侦听器触发多次。
即使 Symfony 建议使用嵌入式控制器将动态内容插入到基本模板中,这是否被认为是不好的做法?
创建一个Twig extension来解决这个问题会不会更好?据我所知,Twig 扩展通常只用于简单的东西,比如食谱中的 price
示例,但我不明白为什么它不能用于更复杂的、与数据库连接的东西。我只是不确定该怎么做。
感谢提供示例。
可能相关?: Symfony Controller executed multiple Time
只有为主请求执行了事件侦听器才能进行重定向:
use Symfony\Component\HttpKernel\HttpKernelInterface;
// ...
if ($event->isMasterRequest() && $event->getRequest()->get('_route') != 'user_change_password') {
$response = new RedirectResponse($this->router->generate('user_change_password'));
$event->setResponse($response);
}
如果您仍然绑定到 Symfony 2.3,您可以使用 getRequestType()
方法将其 return 值与 HttpKernelInterface
中的 MASTER_REQUEST
常量进行比较(这就是isMasterRequest()
内部执行):
use Symfony\Component\HttpKernel\HttpKernelInterface;
// ...
if (HttpKernelInterface::MASTER_REQUEST === $event->getRequestType() && $event->getRequest()->get('_route') != 'user_change_password') {
$response = new RedirectResponse($this->router->generate('user_change_password'));
$event->setResponse($response);
}
在我的 Symfony 项目中,我遇到了一个关于 kernel.request
event listeners firing multiple times when embedded Twig controllers 的奇怪问题。
在我的自定义事件侦听器中,我有一个事件侦听器,如果存在特定条件(在本例中为过期密码),它会发送重定向响应。为了防止重定向循环,我检查了我们是否已经在页面上:
if ($event->getRequest()->get('_route') != 'user_change_password') {
$response = new RedirectResponse($this->router->generate('user_change_password'));
$event->setResponse($response);
}
但这并没有阻止重定向循环。在我添加日志记录之前,我不知道嵌入式控制器会触发 kernel.request
事件(事后看来很明显,因为这些嵌入式控制器通过发送 "sub-request" 来工作)。我在 base twig 模板中有一个嵌入式控制器,用于检查任何警报消息并显示它们。
鉴于以上,我如何
- 能够将动态内容插入基本模板(所有其他模板扩展),并且
- 没有
kernel.request
事件侦听器触发多次。
即使 Symfony 建议使用嵌入式控制器将动态内容插入到基本模板中,这是否被认为是不好的做法?
创建一个Twig extension来解决这个问题会不会更好?据我所知,Twig 扩展通常只用于简单的东西,比如食谱中的 price
示例,但我不明白为什么它不能用于更复杂的、与数据库连接的东西。我只是不确定该怎么做。
感谢提供示例。
可能相关?: Symfony Controller executed multiple Time
只有为主请求执行了事件侦听器才能进行重定向:
use Symfony\Component\HttpKernel\HttpKernelInterface;
// ...
if ($event->isMasterRequest() && $event->getRequest()->get('_route') != 'user_change_password') {
$response = new RedirectResponse($this->router->generate('user_change_password'));
$event->setResponse($response);
}
如果您仍然绑定到 Symfony 2.3,您可以使用 getRequestType()
方法将其 return 值与 HttpKernelInterface
中的 MASTER_REQUEST
常量进行比较(这就是isMasterRequest()
内部执行):
use Symfony\Component\HttpKernel\HttpKernelInterface;
// ...
if (HttpKernelInterface::MASTER_REQUEST === $event->getRequestType() && $event->getRequest()->get('_route') != 'user_change_password') {
$response = new RedirectResponse($this->router->generate('user_change_password'));
$event->setResponse($response);
}