在我的Symfony2.2应用程序中,我使用onKernelTerminate EventListener,这样我可以在呈现响应后执行一些“繁重”处理,以便用户获得更快的响应时间。
在我的控制器中,我在请求上设置了一个属性,以便在事件侦听器运行时,可以使用该属性来确定是否存在某些内容以及要处理的内容。
这完全适用于我的开发环境以及未启用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;
}
答案 0 :(得分:1)
我找到了答案 - 我的困惑来自于不知道如何在单个请求中在服务之间传递信息。 AppCache有点像红鲱鱼(虽然我仍然不知道为什么它会重置对请求的更改)。
我认为唯一的方法是设置请求的属性,以便侦听服务可以从请求中提取。事实上,服务在请求中是持久的 - 因此服务本身可以跟踪onKernelTerminate事件后它需要做什么。
我创建了服务的私有属性(例如$ itemsToPersist),并在此过程中向该数组添加项目。
然后在监听器onKernelTerminate方法中:
$service = $this->container->get('your_service');
$service->persistItems();
只需调用可循环执行itemsToPersist数组的方法,并执行任何需要执行的操作。
无需在请求中传递内容!
答案 1 :(得分:0)
关于您的原始问题:这可能发生,因为Symfony HttpCache
内核克隆了原始请求对象,该对象将传递给kernel.terminate
事件。因此,kernel.terminate
事件中不存在对克隆的请求对象所做的任何更改。见https://github.com/symfony/symfony/issues/23546