用了terminate中间件之后,就想看看为什么页面(客户端)输出之后,terminate方法还能继续执行,猜想肯定是ob族的函数起作用,flush出去之后,php的生命周期还没结束,还能继续执行其他方法。追代码验证一下。
1. $app->run();一切的起点。
2. run方法位于
\vendor\laravel\lumen-framework\src\Concerns\RoutesRequests.php
的473行,方法体是这样的
/**
* Run the application and send the response.
*
* @param SymfonyRequest|null $request
* @return void
*/
public function run($request = null)
{
$response = $this->dispatch($request);
if ($response instanceof SymfonyResponse) {
$response->send();
} else {
echo (string) $response;
}
if (count($this->middleware) > 0) {
$this->callTerminableMiddleware($response);
}
}
$response的send方法具体路径为
\vendor\symfony\http-foundation\Response.php
方法体如下:
public function send()
{
$this->sendHeaders();
$this->sendContent();
if (function_exists('fastcgi_finish_request')) {
fastcgi_finish_request();
} elseif ('cli' !== PHP_SAPI) {
static::closeOutputBuffers(0, true);
}
return $this;
}
在fastcgi模式下
使用fastcgi_finish_request
(PHP 5 >= 5.3.3, PHP 7)
fastcgi_finish_request — 冲刷(flush)所有响应的数据给客户端
在非fastcgi和非cli模式下
public static function closeOutputBuffers($targetLevel, $flush)
{
$status = ob_get_status(true);
$level = count($status);
// PHP_OUTPUT_HANDLER_* are not defined on HHVM 3.3
$flags = defined('PHP_OUTPUT_HANDLER_REMOVABLE') ? PHP_OUTPUT_HANDLER_REMOVABLE | ($flush ? PHP_OUTPUT_HANDLER_FLUSHABLE : PHP_OUTPUT_HANDLER_CLEANABLE) : -1;
while ($level-- > $targetLevel && ($s = $status[$level]) && (!isset($s['del']) ? !isset($s['flags']) || ($s['flags'] & $flags) === $flags : $s['del'])) {
if ($flush) {
ob_end_flush();
} else {
ob_end_clean();
}
}
}
果然就是ob_end_flush