phpEnv默认配置破坏SSE,因其统一启用fastcgi_buffering和proxy_buffering并设短超时,导致SSE数据被缓存、延迟甚至整包返回;需在location中设fastcgi_buffering off、fastcgi_read_timeout 86400、add_header X-Accel-Buffering "no",并配合PHP层正确header与flush。

phpEnv 默认的 Nginx 配置完全不兼容 SSE,直接代理 PHP 输出的 text/event-stream 会卡住、延迟、甚至整包返回——根本原因在于它默认开启 proxy_buffering 和 fastcgi_buffering,且超时极短。
为什么 phpEnv 的默认配置会破坏 SSE
phpEnv 是面向 PHP 开发者的一键环境包,Nginx 配置偏重「快速响应传统页面」,而非长连接流式场景。它对所有 location 统一启用:proxy_buffering on(若走反向代理)、fastcgi_buffering on(PHP-FPM 直连时),同时 proxy_read_timeout 默认仅 60 秒。SSE 要求:数据逐条实时透传 + 连接保持数分钟至数小时 —— 这两者天然冲突。
-
fastcgi_buffering on会让 Nginx 等 PHP-FPM 把整个响应“吐完”才转发,SSE 的data: ...\n\n行被攒着不发 -
proxy_buffering on在反向代理模式下同样缓存后端响应,进一步加延迟 -
proxy_read_timeout 60导致空闲几秒没数据就断连,浏览器触发重连,造成“闪断”感 - 缺少
X-Accel-Buffering: no响应头,部分 Nginx 版本仍会内部缓冲
必须改的三项核心配置(针对 PHP-FPM 模式)
phpEnv 默认用的是 fastcgi_pass 直连 PHP-FPM,不是 proxy_pass,所以重点在 fastcgi_* 系列指令,而非 proxy_*:
- 在对应
location ~ \.php$或 SSE 专用路径(如location /api/sse)里,添加:fastcgi_buffering off - 设置超时:
fastcgi_read_timeout 86400(24 小时,避免被中断) - 强制透传并禁用缓冲:
fastcgi_hide_header X-Accel-Buffering+add_header X-Accel-Buffering "no"
注意:不要写 proxy_buffering off,它对 FastCGI 无效;也不要删 fastcgi_param SCRIPT_FILENAME 等基础参数,只叠加这三项。
立即学习“PHP免费学习笔记(深入)”;
PHP 后端必须配合做的两件事
Nginx 配对只是半边,PHP 层不配合照样失败:
- 输出前必须发送正确 header:
header('Content-Type: text/event-stream');+header('Cache-Control: no-cache');+header('X-Accel-Buffering: no'); - 每次输出事件后,必须调用
ob_flush(); flush();(且确保output_buffering = Off或设为0在php.ini中)
常见坑:echo "data: hello\n\n" 后没 flush(),或 PHP 开启了 zlib.output_compression,都会让数据滞留在 PHP 层无法到达 Nginx。
验证是否生效的三个关键检查点
别只看浏览器控制台有没有报错,要抓真实链路:
- 用
curl -N http://localhost/api/sse(-N禁用 curl 缓冲),观察是否逐行实时输出,而不是等几秒后一次性刷出全部 - 打开 Chrome DevTools → Network → 找到 SSE 请求 → 查看 Response Headers 是否含
X-Accel-Buffering: no和Content-Type: text/event-stream - 检查 Nginx error.log,搜索
upstream timed out或broken pipe,有则说明fastcgi_read_timeout还不够大或 PHP 进程崩溃了
最易被忽略的是:phpEnv 的 Nginx 配置常被拆成多个 include 文件(如 vhost/*.conf、php-fpm.conf),改完主配置记得确认实际生效的是哪一份,必要时用 nginx -t 和 nginx -T 检查最终合并结果。



















