stream_context_create设超时需分设连接超时(timeout)和读取超时(http[read_timeout]),后者PHP 8.0+原生支持,低版本仅能通过timeout兼顾;常见错误是仅设timeout导致流式响应被过早中断。

stream_context_create 怎么设超时?
PHP 的 stream_context_create 本身不支持「重试」,只管单次请求的连接和读取超时。超时必须拆成两个参数:连接阶段(timeout)和数据接收阶段(http[read_timeout]),后者在 PHP 8.0+ 才被原生支持,低版本只能靠 timeout 兼容覆盖。
常见错误是只写 timeout,结果大模型返回慢(比如流式响应耗时 30 秒),但 PHP 在 10 秒就断了——因为没显式设读取超时,老版本默认用 timeout 值硬套在整条流上。
- PHP timeout 同时控制连接 + 读取,设大一点(如
60),但无法精细区分 - PHP ≥ 8.0:可分开设,
timeout控连接(建议5),http[read_timeout]控响应体接收(建议120) - 别用
http[timeout]—— 这是无效键名,PHP 不识别
怎么加重试逻辑?
重试必须自己写,stream_context_create 不提供自动重试。典型做法是封装一个带指数退避的循环,每次失败后 sleep 再重发。重点不是“能不能重试”,而是“重试时要不要复用 context”以及“哪些错误值得重试”。
- 每次重试都该调用新的
stream_context_create,避免旧 context 残留状态(比如已关闭的 socket) - 只对网络层错误重试:
Connection refused、Operation timed out、Failed to open stream;别对 HTTP 4xx/5xx 自动重试(比如 429 是限流,重试只会更糟) - 推荐最多 3 次,间隔从 100ms 开始指数增长(100ms → 300ms → 900ms),避免压垮 AI 服务端
- 示例关键片段:
$retries = 0; while ($retries < 3) { $ctx = stream_context_create($options); $res = @file_get_contents($url, false, $ctx); if ($res !== false || !in_array($http_response_header[0] ?? '', ['HTTP/1.1 502', 'HTTP/1.1 503', 'HTTP/1.1 504'])) { break; } $retries++; usleep(100000 * pow(3, $retries - 1)); }
POST 请求发 JSON 到 AI 接口要注意什么?
AI 接口(如 OpenAI、Ollama)基本要求 Content-Type: application/json 和正确编码的 JSON body,但 stream_context_create 不会自动序列化或设置 header,漏掉任一都会 400 或 415。
立即学习“PHP免费学习笔记(深入)”;
-
http[content]必须是字符串,不是数组 —— 要先json_encode($data),再赋值 -
http[header]里必须显式写Content-Type: application/json,不能依赖默认值 - 如果接口需要 token 认证,
Authorization: Bearer xxx也得手动塞进header字符串,多个 header 用\r\n分隔 - 别忽略
http[method],默认是 GET,AI 接口几乎全是 POST,不设就是错的
为什么 file_get_contents 返回 false 却没报错?
因为 @file_get_contents 屏蔽了 warning,而真实错误藏在 $http_response_header 或 error_get_last() 里。尤其调 AI 接口时,经常遇到连接成功但返回空内容(比如 200 空体、或 chunked 编码解析失败),这时候光看返回值会误判。
- 务必检查
$http_response_header是否存在,第一行是否为HTTP/1.1 200 - 用
error_get_last()捕获底层 socket 错误,比如Connection reset by peer就说明服务端主动断连了 - 流式响应(SSE)不能用
file_get_contents,它会等整个 body 结束才返回 —— 得换fopen+fread边收边处理 - 调试时临时去掉
@,让 warning 显式抛出,比猜快得多
实际集成 AI 接口时,最常被忽略的是 PHP 版本对 http[read_timeout] 的支持差异,以及把「网络超时」和「AI 生成超时」混为一谈——前者是 TCP 层的事,后者得靠 API 自身的 timeout 参数(如 OpenAI 的 timeout query param),两者要分开控制。



















