PHP调用文生图接口频繁掉线主因是连接未复用:需设CURLOPT_FORBID_REUSE=false、复用同一cURL句柄、手动添加Keep-Alive头、轮询时禁用超时限制,并在单脚本内完成提交与轮询闭环。

PHP 调用文生图接口频繁掉线,不是网络不稳,而是默认的 fsockopen 或 cURL 连接被服务端主动断开——多数图像生成 API(如 SiliconCloud、LiblibAI、通义万相)对空闲连接超时限制极严,通常在 30–60 秒内强制关闭。PHP 默认未启用长连接复用,每次请求都新建 TCP 连接,轮询状态时极易遭遇 Connection reset by peer 或 502 Bad Gateway。
为什么 cURL 默认不保持长连接?
cURL 的 CURLOPT_HTTPHEADER 不自动带 Connection: keep-alive,且未显式设置 CURLOPT_FORBID_REUSE 和 CURLOPT_FRESH_CONNECT 时,PHP-cURL 实际行为是“连接用完即关”,尤其在 CLI 模式下无持久化上下文。更关键的是:即使加了 Keep-Alive 头,若服务端返回 Connection: close(常见于负载均衡层),连接仍会被断开。
配置 CURLOPT_FORBID_REUSE = false + 复用 cURL 句柄
必须同时满足两个条件才能真正复用连接:
-
CURLOPT_FORBID_REUSE设为false(默认是true,即禁止复用) - 同一
cURL句柄连续调用curl_exec(),而非每次curl_init()+curl_close() - 手动添加
Connection: keep-alive和Keep-Alive: timeout=60, max=100头(部分服务如 SiliconCloud 显式依赖该头判断是否维持连接)
示例关键段:
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://api.siliconflow.com/v1/images/generations");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FORBID_REUSE, false); // ← 关键!
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Authorization: Bearer YOUR_KEY",
"Content-Type: application/json",
"Connection: keep-alive",
"Keep-Alive: timeout=60, max=100"
]);
// 第一次请求:提交任务
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([...]));
$response1 = curl_exec($ch);
// 第二次请求:轮询 task_id(复用同一 $ch)
curl_setopt($ch, CURLOPT_URL, "https://api.siliconflow.com/v1/images/tasks/TASK_ID");
curl_setopt($ch, CURLOPT_POSTFIELDS, '');
$response2 = curl_exec($ch); // 此次不会重建 TCP 连接
轮询阶段必须禁用 CURLOPT_TIMEOUT_MS
文生图任务轮询常需等待 10–45 秒,但若设了 CURLOPT_TIMEOUT_MS = 10000(10秒),中间任何一次超时都会导致句柄失效,后续请求被迫新建连接,立刻触发掉线。正确做法是:
立即学习“PHP免费学习笔记(深入)”;
- 首次提交任务用短超时(如
15000ms) - 轮询时改用
CURLOPT_TIMEOUT_MS = 0(不限时),或至少设为60000ms - 配合
CURLOPT_CONNECTTIMEOUT_MS单独控制建连阶段(建议5000ms),避免卡死在 DNS 或握手
CLI 环境下 cURL 句柄生命周期易被忽略
PHP CLI 没有请求生命周期管理,$ch 变量作用域结束即销毁句柄。若把轮询逻辑拆成多个独立脚本(如 submit.php → poll.php),cURL 句柄无法跨进程复用,长连接毫无意义。必须:
- 单脚本内完成提交 + 轮询闭环(推荐)
- 或使用
pcntl_fork()让子进程继承句柄(高阶,需注意资源竞争) - 绝对避免通过
shell_exec("php poll.php")启动新进程轮询
最易被忽略的一点:某些 SDK 封装(如 siliconflow-php)内部默认每次新建 cURL 实例,你得翻源码确认是否暴露了句柄复用开关——没有就别用封装,直接手写 cURL 控制流。



















