




Nginx默认缓冲PHP响应导致实时输出失效,需在location ~ .php$中同时关闭proxy_buffering off、fastcgi_buffering off和fastcgi_request_buffering off,并配合PHP端ob_implicit_flush(true)、禁用手动缓冲及逐段flush()。
Nginx在收到PHP-FPM返回的响应前,会先缓存一部分数据(通常至少4KB),再一次性转发给客户端。这意味着即使PHP用了flush()、ob_flush(),浏览器也收不到中间输出——不是PHP没生效,而是Nginx卡住了。
关键配置项有三个,缺一不可:
proxy_buffering off;(若用proxy_pass转发到PHP-FPM)fastcgi_buffering off;(更常见,因多数用fastcgi_pass)fastcgi_request_bu
ffering off;(防止Nginx提前读完整个请求体,干扰流式响应)这些要放在location ~ \.php$块内,不是server或http全局。只关proxy_buffering而漏掉fastcgi_buffering,依然无效。
Nginx配置只是前提,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);
}
即使Nginx和PHP都配对了,浏览器也可能等满1KB才渲染第一行——这是客户端行为,非服务端问题。解决办法很简单:开头先输出足够多空格或注释,比如str_repeat(" ", 1024),骗过浏览器的“启动阈值”。这个细节常被忽略,导致调试时以为配置失败。