1

在我的 Symfony 项目中,我遇到了一个奇怪的问题,即在使用嵌入式 Twig 控制器时,kernel.request 事件监听器会多次触发。

在我的自定义事件侦听器中,我有一个事件侦听器,如果存在特定条件(在这种情况下是过期密码),它会发送重定向响应。为了防止重定向循环,我检查了我们是否已经在页面上:

if ($event->getRequest()->get('_route') != 'user_change_password') {
    $response = new RedirectResponse($this->router->generate('user_change_password'));
    $event->setResponse($response);
}

但这并没有停止重定向循环。在我添加日志记录之前,我不知道嵌入式控制器会触发kernel.request事件(事后看来很明显,因为这些嵌入式控制器通过发送“子请求”来工作)。我在基本树枝模板中有一个嵌入式控制器,用于检查任何警报消息并显示它们。

鉴于上述情况,我怎么能

  1. 能够将动态内容插入基本模板(所有其他模板都扩展),并且
  2. 没有kernel.request事件侦听器多次触发。

尽管 Symfony 建议使用嵌入式控制器将动态内容插入到基本模板中,但这是否被认为是不好的做法?

创建一个Twig 扩展来解决这个问题会更好吗?从我所见,Twig 扩展通常只用于简单的东西,比如price食谱中的例子,虽然我不明白为什么它不适用于更复杂的、与数据库连接的东西。我只是不确定如何做到这一点。

例子值得赞赏。


可能相关?:Symfony 控制器多次执行

4

1 回答 1

4

You could do the redirection only if the event listener is executed for the master request:

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);
}

If you are still bound to Symfony 2.3, you can use the getRequestType() method compare its return value with the MASTER_REQUEST constant from the HttpKernelInterface (that's what isMasterRequest() does internally):

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);
}
于 2016-05-19T19:10:05.870 回答