Nginx默认缓冲PHP响应导致实时输出失效,需在location ~ .php$中同时关闭proxy_buffering off、fastcgi_buffering off和fastcgi_request_buffering off,并配合PHP端ob_implicit_flush(true)、禁用手动缓冲及逐段flush()。

PHP实时输出时Nginx默认会缓冲响应
Nginx在收到PHP-FPM返回的响应前,会先缓存一部分数据(通常至少4KB),再一次性转发给客户端。这意味着即使PHP用了flush()、ob_flush(),浏览器也收不到中间输出——不是PHP没生效,而是Nginx卡住了。
必须关闭Nginx的proxy_buffering和启用fastcgi_buffering
关键配置项有三个,缺一不可:
-
proxy_buffering off;(若用proxy_pass转发到PHP-FPM) -
fastcgi_buffering off;(更常见,因多数用fastcgi_pass) -
fastcgi_request_buffering off;(防止Nginx提前读完整个请求体,干扰流式响应)
这些要放在location ~ \.php$块内,不是server或http全局。只关proxy_buffering而漏掉fastcgi_buffering,依然无效。
PHP端需配合禁用输出缓冲并逐段输出
Nginx配置只是前提,PHP自己也得“不攒着”:
立即学习“PHP免费学习笔记(深入)”;
- 开头调用
ob_implicit_flush(true),让每个echo自动触发输出 - 避免使用
ob_start()或任何手动输出缓冲层 - 每段输出后加
flush()和ob_flush()(部分PHP版本需两者都调) - 若用
readfile()或大文件输出,记得设set_time_limit(0)防超时
示例片段:
ob_implicit_flush(true);
for ($i = 0; $i < 5; $i++) {
echo "step {$i}\n";
flush();
ob_flush();
sleep(1);
}
Chrome/Firefox对首屏空白有最小长度限制
即使Nginx和PHP都配对了,浏览器也可能等满1KB才渲染第一行——这是客户端行为,非服务端问题。解决办法很简单:开头先输出足够多空格或注释,比如str_repeat(" ", 1024),骗过浏览器的“启动阈值”。这个细节常被忽略,导致调试时以为配置失败。











