PHP实时输出轮询无反应是因为输出缓冲未关闭,需调用ob_flush()和flush()并配置Nginx fastcgi_buffering off;响应头须设Cache-Control、X-Accel-Buffering等防缓存;轮询间隔应动态调整,避免盲目高频;注意PHP-FPM、HTTPS、浏览器并发等底层限制。
因为默认情况下 PHP 会缓冲输出,echo 或 print 的内容不会立刻发给浏览器,而是等脚本结束或缓冲区满才刷出。轮询(比如用 fetch 轮着请求一个 PHP 脚本)看到的永远是“一次性吐完”,根本不是实时流。
关键不是轮询逻辑写得对不对,而是服务端压根没把数据分段送出去。
ob_end_flush() 或 ob_end_clean(),且确保之前没开启过缓冲(检查 output_buffering 配置)flush() 和 ob_flush() 要成对调用,顺序不能反:先 ob_flush() 清 PHP 用户层缓冲,再 flush() 推给 Web 服务器(如 Apache/Nginx)fastcgi_buffering off;,否则无论 PHP 怎么 flush 都会被 Nginx 拦住轮询本质是短连接反复请求,不是长连接流式响应,所以不需要 SSE 或 WebSocket 头。但要避免被代理、CDN 或浏览器缓存干扰,必须显式控制响应头:
header('X-Accel-Buffering: no'); 告诉 Nginx 别缓冲header('Cache-Control: no-cache, must-revalidate, max-age=0'); 防浏览器/中间件缓存响应体header('Content-Type: text/plain; charset=utf-8');(或 application/json),避免 MIME 类型触发浏览器额外解析或缓存策略204 No Content 或 304 Not Modified —— 这类状态码会让浏览器跳过响应体读取,轮询就收不到数据没有固定值,取决于业务延迟容忍度和后端压力。盲目设 100ms 可能打爆服务器,设 5s 又显得“卡顿”。真实场景建议按需分级:

fetch(url, { signal: AbortSignal.timeout(3000) }),避免单次请求挂起整个轮询链If-None-Match 或参数比对,无变更直接返回 304 减少负载很多问题不是代码写错,而是环境或协议层面卡住:
fastcgi_finish_request() 会提前关闭连接,之后的 flush() 全失效 —— 别在它之后还试图输出flush(),或强制开启 output_buffering = 4096 且不可改,这种环境根本不适合轮询实时输出flush() 后追加空格或换行(如 echo str_repeat(" ", 512);)凑够 TCP 包大小,触发立即发送轮询不是万能兜底方案,当延迟要求严苛或并发高时,该切 Server-Sent Events 或 WebSocket 就别硬扛 —— PHP 输出控制只是其中一环,不是银弹。