嵌入式Twig控制器会导致kernel.request事件多次触发

时间:2016-05-19 18:50:46

标签: events symfony twig-extension

在我的Symfony项目中,kernel.request event listeners在使用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事件(事后看来很明显,因为这些嵌入式控制器通过发送"子请求" )。我有一个基础树枝模板的嵌入式控制器,可以检查任何警报消息并显示它们。

鉴于以上,我该如何

  1. 能够将动态内容插入基本模板(所有其他模板都扩展),AND
  2. 没有kernel.request个事件侦听器多次触发。
  3. 即使Symfony建议使用嵌入式控制器将动态内容插入基础模板,这被认为是不好的做法吗?

    创建Twig extension以解决此问题会更好吗?根据我所看到的,Twig扩展通常仅用于简单的内容,例如食谱中的price示例,但我不明白为什么它不适合更复杂的工作,数据库连接的东西。我只是不确定如何做到这一点。

    赞赏例子。

    可能相关?:Symfony Controller executed multiple Time

1 个答案:

答案 0 :(得分:4)

只有在为主请求执行事件侦听器时,才能执行重定向:

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()方法将其返回值与MASTER_REQUEST中的HttpKernelInterface常量进行比较(这是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);
}