如何在标头发送到客户端后处理Symfony2中的Session?

时间:2015-09-11 19:58:04

标签: php symfony session kernel terminate

我在Symfony2控制器中有一个操作,它将响应发送回客户端(详见here)。在函数发出响应之后,我有一个侦听onkernelTerminate event的事件订阅者,因为在响应发送到客户端之后我将做一些繁重的工作。

除了代码中引用利用Session的服务的行之外,所有内容似乎都正常工作,这需要它来存储令牌并最终与外部API通信。

错误当然是:由于标头已经发送,因此无法启动会话。

有没有办法启动会话甚至已发送标头?或者什么是更好的方法来处理这个问题?

1 个答案:

答案 0 :(得分:0)

我最后通过从传入请求获取会话并将其存储到我的操作控制器中的本地变量来修复此问题,然后确保会话已激活或启动:

use Symfony\Component\HttpFoundation\Request;

public function myFunctionAction(Request $request) {
   $session = $request->getSession();
   $session->start();

接下来,我立即将响应和标题发送给客户端:

    ob_start();
    $response = new Response('Status: OK', 200);
    echo $response; // send the response
    header('Connection: close');
    header('Content-Length: ' . ob_get_length());
    ob_end_flush();
    if (ob_get_level() > 0) {
        ob_flush();
    }
    flush();

然后代码继续像往常一样繁重的工作。但是,解决此问题的关键是确保利用Session的服务为其他人提供选项,以便在服务中保存或不保存会话。如果会话被保存,那么它将不再处于活动状态并且它将被关闭,一旦关闭,您就无法再次启动它,因为已经发送了标头。但是,引用该服务的客户端代码应该在最后保存并关闭会话。

我最终没有收听 kernel.terminate事件,因为在我的情况下不需要它。