php实时输出接口返回实时数据_php实时输出api设计【步骤】

9次阅读

php实时输出需逐层关闭缓冲:禁用nginx gzip/fastcgi_buffering、apache mod_deflate、PHP output_buffering/zlib压缩,首行输出1024空格绕过chrome缓冲,配合ob_flush()和flush(),并设置SSE响应头及心跳保活。

php实时输出接口返回实时数据_php实时输出api设计【步骤】

PHP 实时输出接口为什么用 flush() 没反应?

多数人卡在这一步:写了 echoob_flush()flush(),但浏览器还是等全部执行完才显示。根本原因不是 PHP 代码错了,而是中间环节在“拦路”。

  • Web 服务器(如 Nginx)默认开启 gzip 或缓冲响应体,会攒够一定字节才发;需关闭:gzip off;(Nginx)或设置 fastcgi_buffering off;
  • Apache 的 mod_deflate 同样会压缩并缓存输出,需禁用或配置 SetEnv no-gzip 1
  • PHP 自身的输出缓冲链有好几层:output_bufferingphp.ini)、zlib.output_compression 必须关掉,建议在脚本开头加:ini_set('output_buffering', 'Off'); ini_set('zlib.output_compression', false);
  • 浏览器也可能缓冲——特别是 Chrome 对小响应体有最小字节数要求(约 1KB),可在首行输出 1024 字符空格(str_repeat(' ', 1024))绕过

while(true) 长轮询还是 EventSource

别硬写长轮询。PHP 天然不适合维持大量并发长连接,while(true) + sleep() 在 Apache/PHP-FPM 下极易耗尽 worker 进程,且无法优雅中断。

  • EventSource(SSE)是更轻量的选择:前端new EventSource('/stream.php')后端保持连接、按格式输出 data: ...nn,PHP 只需每轮 echo "data: ".json_encode($msg)."nn"; ob_flush(); flush();
  • 必须设置响应头:header('Content-Type: text/event-stream'); header('Cache-Control: no-cache'); header('X-Accel-Buffering: no');(最后一项专治 Nginx 缓冲)
  • 若需双向实时(如聊天),SSE 不行,得换 websocket(用 swooleworkerman 实现),PHP 原生不支持服务端 WebSocket

ob_end_flush()ob_flush() 到底该用哪个?

混淆点在于 PHP 输出缓冲层级。简单说:ob_flush() 清当前一级输出缓冲区,flush() 把 Web 服务器缓存里的内容真正推给客户端;ob_end_flush() 是清完还销毁缓冲区——一旦调了,后续 echo 就直通底层,不能再用 ob_*() 控制。

  • 推荐固定组合:ob_flush(); flush();(反复用)
  • 如果开头用了 ob_start(),结尾想彻底释放,才用 ob_end_flush();但实时流中一般不需要销毁缓冲区
  • 注意顺序:必须先 ob_flush()(把 PHP 用户缓冲刷到 SAPI 层),再 flush()(把 SAPI 缓冲推给客户端),反了无效

如何避免超时和连接被意外断开?

PHP 默认 max_execution_time=30,Nginx 默认 proxy_read_timeout=60,这些都会杀死长连接。不调它们,实时流活不过一分钟。

立即学习PHP免费学习笔记(深入)”;

  • PHP 端:脚本开头加 set_time_limit(0);,并确保 ignore_user_abort(true)(防止用户关页面导致脚本终止)
  • Nginx 端:在 location 块里配 proxy_read_timeout 3600;proxy_buffering off;chunked_transfer_encoding off;
  • 务必加心跳保活:每 15–30 秒输出一次注释行(echo ": keep-alivenn"; ob_flush(); flush();),避免代理或防火墙因空闲断连

实际跑通的关键不在某一行代码,而在整条链路——PHP、Web 服务器、浏览器、中间代理,任何一环缓冲没关,就全白搭。最容易漏的是 Nginx 的 fastcgi_buffering 和浏览器的 1KB 缓冲门槛。

text=ZqhQzanResources