PHP FPM环境下实现ChatGPT API文本流式输出的方案
在PHP FPM环境下实现ChatGPT流式输出的解决方案
一、修正代码结构问题
你的PHP脚本后直接拼接HTML内容,会污染SSE(Server-Sent Events)流,导致EventSource无法正确解析。需将流式接口与页面HTML完全分离:
- 创建独立的SSE接口文件(如
ai_stream.php),仅处理流式输出:
<?php require_once("openai.php"); $open_ai = new OpenAi("你的OpenAI密钥"); $opts = [ 'prompt' => "Write an essay about the top 5 colleges in the United States", 'temperature' => 0.9, "max_tokens" => 2000, "frequency_penalty" => 0, "presence_penalty" => 0.6, "stream" => true, ]; // 设置SSE必备响应头 header('Content-Type: text/event-stream'); header('Cache-Control: no-cache'); header('Connection: keep-alive'); header('X-Accel-Buffering: no'); // 强制禁用Nginx加速缓冲 // 彻底关闭所有输出缓冲 while (ob_get_level() > 0) { ob_end_clean(); } $open_ai->completion($opts, function ($curl_info, $data) { // 按OpenAI流式响应格式拆分内容,输出符合SSE规范的格式 $lines = explode("\n", trim($data)); foreach ($lines as $line) { if (empty($line)) continue; if ($line === "data: [DONE]") { echo "data: [DONE]\n\n"; } else { $jsonStr = substr($line, 6); // 去掉前缀"data: " echo "data: {$jsonStr}\n\n"; } } // 强制刷新输出到客户端 flush(); return strlen($data); }); ?>
- 创建独立的页面HTML文件(如
index.html):
<!DOCTYPE html> <html lang="en"> <meta charset="UTF-8"> <title>AI流式输出演示</title> <meta name="viewport" content="width=device-width,initial-scale=1"> <body> <div id="divID">Hello</div> <script> var eventSource = new EventSource("/ai_stream.php"); var div = document.getElementById('divID'); eventSource.onmessage = function (e) { if (e.data === "[DONE]") { div.innerHTML += "<br><br>生成完成"; eventSource.close(); // 主动关闭连接 } else { try { var data = JSON.parse(e.data); div.innerHTML += data.choices[0].text; } catch (err) { console.error("响应解析错误:", err); } } }; eventSource.onerror = function (e) { console.error("连接异常:", e); eventSource.close(); }; </script> </body> </html>
二、调整PHP FPM配置
修改PHP FPM的站点配置文件(如www.conf),禁用输出缓冲:
php_admin_value[output_buffering] = off php_admin_flag[implicit_flush] = on
修改后重启PHP FPM服务:
# 以Ubuntu系统为例 sudo systemctl restart php-fpm
三、调整Web服务器配置(以Nginx为例)
如果使用Nginx作为反向代理,需禁用所有缓冲确保实时流式传输,在站点location块中添加:
location /ai_stream.php { fastcgi_pass unix:/run/php/php8.2-fpm.sock; # 根据你的PHP版本调整路径 fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; # 禁用缓冲相关设置 proxy_buffering off; fastcgi_buffering off; gzip off; add_header Cache-Control no-cache; add_header Connection keep-alive; }
修改后重启Nginx:
sudo systemctl restart nginx
四、验证配置有效性
在SSE接口开头添加以下代码,确认输出缓冲已关闭:
var_dump(ini_get('output_buffering')); // 应返回"0"或空字符串 var_dump(ob_get_level()); // 应返回0
关键注意事项
- 禁止在SSE接口中输出任何无关内容(包括空格、换行),否则会导致EventSource解析失败
- 部分OpenAI封装库需额外配置curl的
CURLOPT_BUFFERSIZE参数,控制分块传输的大小 - 生产环境中不要硬编码API密钥,建议通过环境变量注入
内容的提问来源于stack exchange,提问作者Jimmison Johnson
相关产品推荐
相关产品推荐

