php请求超时后可自动重试,需手动封装curl或file_get_contents逻辑,控制重试次数(2~3次)、间隔(如sleep(1))及条件(仅网络错误和5xx状态码),guzzle等第三方库提供更稳健的重试中间件。

PHP 请求超时后直接失败,不是必须的;加几行代码就能自动重试,关键在控制重试次数、间隔和判断条件。
用 curl_setopt 设置超时与重试逻辑
原生 curl 本身不支持自动重试,得自己封装。重点是把 CURLOPT_TIMEOUT(总超时)和 CURLOPT_CONNECTTIMEOUT(连接超时)设短一点,再配合循环判断 curl_errno($ch) 或 HTTP 状态码是否异常。
-
CURLOPT_TIMEOUT建议设为 5~10 秒,避免单次卡死太久 - 每次失败后用
sleep(1)或usleep(500000)控制间隔,别立刻重试 - 只对网络错误(如
CURLE_OPERATION_TIMEDOUT、CURLE_COULDNT_CONNECT)和 5xx 状态码重试,404、400 这类业务错误不该重试 - 最多重试 2~3 次,再失败就该让上层处理或记录日志
用 file_get_contents + stream_context_create 的重试写法
如果不用 cURL,file_get_contents 也能实现,但得靠 stream_context_create 控制超时,并手动捕获 Warning 级错误——PHP 默认不抛异常,需提前设置 set_error_handler 或检查返回值是否为 false。
-
http[timeout]对应连接+读取总超时,单位是秒,不能设小数(设 3.5 会截断成 3) - 超时后
file_get_contents返回false,不是异常,所以不能用try/catch捕获 - 若启用了
allow_url_fopen=Off,这条路直接走不通,得切回 cURL
第三方库如 guzzlehttp/guzzle 的重试中间件
Guzzle 自带 RetryMiddleware,比手写更稳,尤其适合并发请求多、需要退避策略(如指数退避)的场景。
立即学习“PHP免费学习笔记(深入)”;
- 需安装
guzzlehttp/guzzle和guzzlehttp/promises - 用
RetryMiddleware::createWithFullDetails()可自定义重试条件,比如只重试ConnectException和状态码 503 - 默认重试间隔是线性增长,想改指数退避得传入自定义
$delay函数 - 注意 Guzzle v7 的异常结构变了:
$e->getResponse()可能为null,得先判空再取状态码
重试不是万能的:服务端正在重启时反复重试可能加剧压力;接口本身有副作用(如扣款)绝不能无脑重试;DNS 解析失败这类问题,换 DNS 或加 hosts 才是根治办法。











