我的理解kernel.terminate
是它在响应返回给客户端后触发.
在我的测试中,看起来并非如此.如果我sleep(10)
在kernel.terminate中调用了一个函数.浏览器也等待10秒钟.处理似乎在发送响应之前发生.
我在配置中有以下内容:
calendar: class: Acme\CalendarBundle\Service\CalendarService arguments: [ @odm.document_manager, @logger, @security.context, @event_dispatcher ] tags: - { name: kernel.event_subscriber }
我的订阅者类:
class CalendarService implements EventSubscriberInterface { public static function getSubscribedEvents() { return array( 'kernel.terminate' => 'onKernelTerminate' ); } public function onKernelTerminate() { sleep(10); echo "hello"; } }
UPDATE
这似乎与Symfony没有发送Content-Length
标题有关.如果我生成它,响应将正确返回.
// app_dev.php ... $kernel = new AppKernel('dev', true); $kernel->loadClassCache(); $request = Request::createFromGlobals(); $response = $kernel->handle($request); // --- START EDITS --- $size = strlen($response->getContent()); $response->headers->set('Content-Length', $size); $response->headers->set('Connection', 'close'); // ---- END EDITS ---- $response->send(); $kernel->terminate($request, $response);
anushr.. 13
这个问题对我的设置非常具体(Nginx,PHP-FCGI,Symfony).
有一些问题导致了这个问题:
symfony中不包括Content-Length
也不Connection: close
头
PHP-FCGI不支持该fastcgi_finish_request
功能
Nginx缓存来自PHP-FCGI的响应,因为Gzip已启用
解决方案是从PHP-FCGI切换到PHP-FPM以获得支持fastcgi_finish_request
.Symfony在执行内核终止逻辑之前在内部调用它,从而最终关闭连接.
解决这个问题的另一种方法是关闭Nginx上的Gzip,但这对我来说不是一个真正的选择.