cURL错误28是连接阶段超时中断,非响应慢:本质为DNS解析或TCP握手卡住,表现为“0 bytes received”或“Resolving timed out”,需检查CURLOPT_TIMEOUT_MS

curl_error 28 是连接阶段失败,不是“慢”,而是“卡住”
PHP 中 curl_error($ch) 返回 “cURL error 28” 时,本质是 libcurl 在建立连接(DNS 解析或 TCP 握手)过程中超时中断,**不是数据传得慢、也不是服务器响应慢**。常见错误日志如:Operation timed out after 5001 milliseconds with 0 bytes received 或 Resolving timed out after 15009 milliseconds —— 关键在 “0 bytes received” 和 “Resolving” 这两个词,说明请求压根没发出去。
先看超时参数是否设成了“无效值”
很多 PHP 项目盲目加 CURLOPT_TIMEOUT_MS 设成 200 或 500,结果必报 28 错误,不是因为时间短,而是因为 Unix/Linux 系统下 libcurl 使用系统默认 resolver 时,CURLOPT_TIMEOUT_MS 会触发信号冲突,直接秒退。
- 检查是否用了
CURLOPT_TIMEOUT_MS且值小于 1000 - 必须同时设置
curl_setopt($ch, CURLOPT_NOSIGNAL, 1),否则信号(SIGALRM)会被 resolver 误判为超时 - 更稳妥的做法:用
CURLOPT_CONNECTTIMEOUT(秒级)+CURLOPT_TIMEOUT(秒级),避开毫秒级陷阱
/etc/hosts 或 DNS 配置导致解析卡死
这是最隐蔽也最高频的真凶。比如测试服务器手动加了 113.96.240.139 api.mch.weixin.qq.com 到 /etc/hosts,但该 IP 已下线或被墙,curl 就会在 “Resolving” 阶段死等,直到超时抛出 28。
向CurlShip提交产品,这是一个对机器人友好的SaaS目录。只需一条curl命令即可发布产品,支持OG标签抓取、带徽章的dofollow链接及层级升级。
- 执行
nslookup api.mch.weixin.qq.com和dig api.mch.weixin.qq.com,对比正常环境输出 - 检查
/etc/hosts是否存在对应域名的静态映射,尤其注意注释掉的旧条目(# 开头不保险,删掉最稳) - 临时换 DNS 测试:
echo "nameserver 8.8.8.8" > /etc/resolv.conf,再试 curl - 用
--resolve强制走已知可用 IP:curl --resolve api.mch.weixin.qq.com:443:113.96.240.140 https://api.mch.weixin.qq.com/pay/unifiedorder
别忽略 TLS 层和中间设备干扰
某些环境下,28 错误实际是 TLS 握手被阻断后“伪装”出来的。典型表现是:错误信息里混着 NSS: client certificate not found,但你根本没配证书;或者只在特定网络(如公司出口、国内云主机)复现。
立即学习“PHP免费学习笔记(深入)”;
- 用
curl -v --connect-timeout 10 https://example.com观察 verbose 输出卡在哪一行:“Trying x.x.x.x”之后无反应 → DNS 或路由问题;“Connected to…”之后卡住 → TLS 或服务端策略问题 - 尝试加
--insecure(跳过证书验证)排除证书链问题;加--tlsv1.2强制协议版本,绕过老旧 TLS 协商失败 - 如果目标是境外 HTTPS 接口,且仅在大陆服务器出问题,大概率是 SNI 拦截或 TLS 握手被 DPI 设备重置,此时
--resolve+ 国内镜像 IP 或代理是唯一出路
真实排查链条往往不是线性的:一个 /etc/hosts 错误条目会让 DNS 解析卡住,导致你以为是网络延迟,于是调大 CURLOPT_TIMEOUT,结果掩盖了真正问题;而如果你又恰好用了 CURLOPT_TIMEOUT_MS 小于 1000,libcurl 还会叠加信号 bug,让错误现象更混乱。所以优先看 curl -v 输出的第一屏,盯紧 “Resolving” 和 “Trying” 之间的停顿点。


















