要实现PHP后端流式输出与前端ChatGPT式打字机效果,核心是使用SSE协议:PHP需禁用输出缓冲、设置正确响应头(如text/event-stream、no-cache、X-Accel-Buffering: no),Nginx/Apache须关闭代理缓冲,前端用EventSource实时接收并渲染,OpenAI调用需启用stream模式并逐行解析delta内容。

要让PHP后端支持流式输出、前端呈现ChatGPT式的“打字机效果”,核心是用Server-Sent Events(SSE)协议打通前后端,而不是等AI响应全部生成完再返回。这个过程看似简单,实则多个环节容易卡住——比如PHP缓冲、Web服务器缓存、HTTP头缺失,都会导致前端一次性收到全部内容,失去逐字显示效果。
PHP端必须关闭输出缓冲并设置正确响应头
PHP默认启用输出缓冲(output_buffering),会把所有echo内容攒在一起发出去。流式输出要求每生成一个token就立即推送,所以必须手动禁用:
- 在脚本开头加 ob_end_flush() 或 ob_implicit_flush(true),强制关闭当前输出缓冲层
- 必须设置以下HTTP头,缺一不可:
Content-Type: text/event-stream; charset=utf-8
Cache-Control: no-cache
Connection: keep-alive
X-Accel-Buffering: no(Nginx反向代理时关键) - 每次发送数据需严格遵循SSE格式:以 data: {json} 开头,结尾用双换行 \n\n;如需发送事件名,可加 event: message
Nginx或Apache需关闭代理缓冲
即使PHP端已正确流式输出,如果Web服务器做了中间缓存,依然会攒包。常见配置调整:
- 在Nginx的location块中添加:
proxy_buffering off;
chunked_transfer_encoding on;
proxy_cache off;
proxy_http_version 1.1; - Apache用户需确保mod_proxy和mod_headers已启用,并在虚拟主机或目录配置中加入:
Header set Cache-Control "no-cache"
SetEnv no-gzip 1(防止gzip压缩破坏流式结构)
前端用EventSource接收并实时渲染
前端无需复杂框架,原生JavaScript即可实现稳定流式消费:
立即学习“PHP免费学习笔记(深入)”;
- 创建 new EventSource('/stream.php'),注意路径需与后端SSE接口一致
- 监听 message 事件,用 JSON.parse(event.data) 解析每个片段
- 推荐将内容追加到DOM前先做防XSS处理(如仅允许纯文本或白名单HTML标签),避免直接 innerHTML
- 务必监听 error 事件并重连,因为SSE连接可能因超时或网络中断断开
OpenAI API调用需开启stream模式并解析delta流
调用OpenAI Chat Completions接口时,不能只关注最终结果,而要边收边转:
- 请求体中必须含 "stream": true,且模型支持流式(gpt-3.5-turbo、gpt-4、gpt-4o均支持)
- OpenAI返回的是多段JSON行(NDJSON),每行是一个完整JSON对象,需逐行读取并提取 choices[0].delta.content
- 注意空content表示token结束,finish_reason === "stop" 才代表完整回答终止
- 建议在PHP中用 curl_setopt($ch, CURLOPT_WRITEFUNCTION, $callback) 自定义写入函数,实时处理每一段响应



















