Symfony2: 为什么传递给Kernel.Terminate EventListener的请求会受到Symfony2中的AppCache影响?

3
在我的Symfony2.2应用程序中,我使用一个onKernelTerminate事件监听器,以便在响应已呈现后进行一段“繁重”的处理,从而使用户获得更快的响应时间。在我的控制器中,我设置了请求上的属性,以便在事件监听器运行时,可以使用该属性来决定是否存在某些内容并对其进行处理。这在我的开发环境和未启用AppCache的测试环境中完美地工作。但是,一旦我启用了AppCache(在我的app.php中)-我想这样做是因为我将其用于所有的HTTP缓存,事件监听器就会停止工作,因为似乎通过onKernelTerminate事件访问的请求具有一个空的属性参数包。在控制器中设置的属性在PostResponseEvent中的请求中不可用。为什么AppCache会产生这种影响?是否有其他方法可以在控制器和事件监听器之间传递数据,并且可以与AppCache一起使用?以下是一小段代码,供您参考:
#in my controller
$request->attributes->set('listener-to-process', 'test');


#in my EventListener:
public function onKernelTerminate(PostResponseEvent $event) {

    $request = $event->getRequest();

    //use this request attribute to decide what to process
    if (!$request->attributes->has('listener-to-process')) {
        return;
    };

    $type = $request->attributes->get('listener-to-process');
    $status = $this->api->persistTag(type);

    return;

}

当您使用AppCache包装类时,控制器永远不会被调用。 - Goran
你是否曾经发现在使用AppCache时,属性参数包为什么会变为空?我目前正在调查一个类似的问题,即onKernelTerminate事件需要请求的完整信息,包括其路由等。 - fritzmg
2个回答

0

我找到了答案 - 我的困惑来自于不知道如何在单个请求中传递信息。AppCache有点误导人(尽管我仍然不知道为什么它会重置请求的更改)。

我以为唯一的方法是设置请求的属性,以便监听服务可以从请求中获取。实际上,服务在请求内是持久的 - 因此服务本身可以跟踪onKernelTerminate事件后需要执行的操作。

我创建了一个服务的私有属性(例如$itemsToPersist),并在过程中向该数组添加项目。

然后在onKernelTerminate方法的监听器中:

$service = $this->container->get('your_service');
$service->persistItems();

只需调用可以循环遍历itemsToPersist数组并执行其所需操作的方法。

无需在请求中传递任何内容!


但是如何在onKernelTerminate方法中检索控制器中计算的数据? - COil

0
关于你的原始问题:这可能是因为Symfony的HttpCache内核克隆了原始请求对象,该对象将传递给kernel.terminate事件。因此,对克隆的请求对象所做的任何更改都不会出现在kernel.terminate事件中。请参见https://github.com/symfony/symfony/issues/23546

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接