简体   繁体   English

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

[英]Symfony2: Why is the Request passed to a Kernel.Terminate EventListener affected by AppCache in Symfony2

In my Symfony2.2 application I am using an onKernelTerminate EventListener so that I can do a piece of "heavy" processing after my response has been rendered so the user receives a faster response time. 在我的Symfony2.2应用程序中,我使用onKernelTerminate EventListener,这样我可以在呈现响应后执行一些“重”处理,以便用户获得更快的响应时间。

In my controller I set an attribute on the request so that when the event listener runs, that attribute can be used to decide if there is something and what to process. 在我的控制器中,我在请求上设置了一个属性,以便在事件侦听器运行时,该属性可用于确定是否存在某些内容以及要处理的内容。

This works perfectly on my dev environment and on a test environment where AppCache is not enabled. 这在我的开发环境和未启用AppCache的测试环境中完美运行。 But as soon as I enable AppCache (in my app.php) - which I want to do because I use it for all my HTTP caching - the event listener stops working because it seems the Request that I access via the Event in onKernelTerminate has an empty attributes parameter bag. 但是一旦我启用AppCache(在我的app.php中) - 我想用它做我所有的HTTP缓存 - 事件监听器停止工作,因为看起来我通过onKernelTerminate中的事件访问的请求有一个空属性参数包。

The attribute I set in the controller isn't available from the request in the PostResponseEvent. 我在PostResponseEvent中的请求中无法使用我在控制器中设置的属性。

Why does AppCache have this effect? 为什么AppCache有这种效果? And is there an alternative way to pass data between my controller and an Event Listener which would work with AppCache? 是否有另一种方法可以在我的控制器和可以与AppCache一起使用的事件监听器之间传递数据?

Here's a snippet of code so you can see: 这是一段代码,您可以看到:

#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;

}

I found the answer - and my confusion came from not knowing how to pass information between services in a single request. 我找到了答案 - 我的困惑来自于不知道如何在单个请求中在服务之间传递信息。 AppCache was a bit of a red-herring (though I still don't know why it resets changes to the request). AppCache有点像红鲱鱼(虽然我仍然不知道为什么它会重置对请求的更改)。

I thought the only way was to set properties of the request so that the listening service could pull from the request. 我认为唯一的方法是设置请求的属性,以便侦听服务可以从请求中提取。 In fact services are persistent within the request - so the service itself can keep track of what it needs to do after the onKernelTerminate event. 事实上,服务在请求中是持久的 - 因此服务本身可以跟踪onKernelTerminate事件之后需要做什么。

I created a private property of the service (eg $itemsToPersist) and during the course of the process add items to that array. 我创建了服务的私有属性(例如$ itemsToPersist),并在此过程中向该数组添加项。

Then in the listener onKernelTerminate method: 然后在监听器onKernelTerminate方法中:

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

just call the method which can loop through the itemsToPersist array and do whatever it needs to do. 只需调用可以遍历itemsToPersist数组的方法,并执行它需要做的任何事情。

No need to pass stuff in the request! 无需在请求中传递内容!

Regarding your original problem: this probably happens because the Symfony HttpCache Kernel clones the original request object which would be passed to the kernel.terminate event. 关于你原来的问题:这可能是因为Symfony HttpCache内核克隆了原始请求对象,该对象将被传递给kernel.terminate事件。 Thus any changes made to the cloned request object are not present in the kernel.terminate event. 因此,对kernel.terminate事件中不存在对克隆的请求对象所做的任何更改。 See https://github.com/symfony/symfony/issues/23546 请参阅https://github.com/symfony/symfony/issues/23546

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM