2019独角兽企业重金招聘Python工程师标准>>>
用了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