curl_exec()返回false时需用curl_errno()和curl_error()定位错误;超时设置要区分curlopt_timeout(总耗时)与curlopt_connecttimeout(连接阶段,含dns);curl_getinfo(..., curlinfo_http_code)仅在curl_exec()成功后有效;ssl错误应配ca证书而非禁用验证。

curl_exec() 返回 false 怎么判断具体错误
直接用 curl_exec() 的返回值做真假判断远远不够——它在超时、DNS失败、连接拒绝等几乎所有错误下都返回 false,但你根本不知道是哪一步挂了。
必须搭配 curl_errno() 和 curl_error() 才能定位:
-
curl_errno($ch)返回整数错误码(比如7是无法连接到主机,28是超时) -
curl_error($ch)返回人类可读的错误字符串,但注意:它只在curl_exec()返回false后才有效 - 别在
curl_exec()前调用curl_error(),此时它可能返回上一次请求的残留信息
超时设置不生效?检查 CURLOPT_TIMEOUT 和 CURLOPT_CONNECTTIMEOUT 区别
很多人设了 CURLOPT_TIMEOUT 却发现 DNS 解析卡住十几秒才报错——因为这个选项只控制「整个请求过程」(含连接、发送、接收),不包括 DNS 查询本身。
- 真正管连接建立阶段(含 DNS 解析、TCP 握手)的是
CURLOPT_CONNECTTIMEOUT,建议设为5或更低 -
CURLOPT_TIMEOUT应略大于CURLOPT_CONNECTTIMEOUT,比如设成10,避免连接刚成功就因总耗时超限被砍掉 - 如果服务端响应极慢但连接快,光靠
CONNECTTIMEOUT拦不住,必须靠TIMEOUT - PHP 7.3+ 支持
CURLOPT_TIMEOUT_MS和CURLOPT_CONNECTTIMEOUT_MS,精度到毫秒,但注意:底层 cURL 版本也得支持,否则自动降级为秒级
curl_getinfo() 拿不到 HTTP 状态码?先确认是否执行成功
curl_getinfo($ch, CURLINFO_HTTP_CODE) 在 curl_exec() 返回 false 时大概率返回 0——不是没状态码,是请求根本没发出去或中途断了。
动态WEB网站中的PHP和MySQL详细反映实际程序的需求,仔细地探讨外部数据的验证(例如信用卡卡号的格式)、用户登录以及如何使用模板建立网页的标准外观。动态WEB网站中的PHP和MySQL的内容不仅仅是这些。书中还提到如何串联JavaScript与PHP让用户操作时更快、更方便。还有正确处理用户输入错误的方法,让网站看起来更专业。另外还引入大量来自PEAR外挂函数库的强大功能,对常用的、强大的包
- 只有
curl_exec()返回非false(即请求完成,哪怕返回 404/500),curl_getinfo(..., CURLINFO_HTTP_CODE)才有意义 - 如果需要统一处理所有情况,建议把状态码提取逻辑放在
curl_exec()成功后,而不是不管结果先取 - 注意
CURLINFO_HTTP_CODE只反映最后一跳的状态码;如果用了重定向(CURLOPT_FOLLOWLOCATION),它返回的是最终响应码,不是第一个
SSL 验证失败(cURL error 60)怎么安全绕过
开发环境遇到 SSL certificate problem: unable to get local issuer certificate(错误码 60),第一反应常是关掉 CURLOPT_SSL_VERIFYPEER——但这等于裸奔,生产环境绝对不能这么干。
- 临时调试可用:
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false),但必须同时加curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false),否则部分版本仍会报错 - 真正解决要配 CA 证书路径:
curl_setopt($ch, CURLOPT_CAINFO, '/path/to/cacert.pem'),推荐用 Mozilla 官方维护的cacert.pem - Windows 下 PHP 自带的
php.ini里可能已配好curl.cainfo,但 CLI 和 Web SAPI 的配置文件可能不同,得分别检查 - 用
curl_setopt($ch, CURLOPT_VERBOSE, true)开启详细日志,能看清 SSL 握手在哪一步失败
立即学习“PHP免费学习笔记(深入)”;
curl 错误处理最麻烦的地方不是写几行判断,而是不同错误码对应的真实网络场景太杂——超时可能是本地 DNS 慢,也可能是远端服务假死;errno=7 可能是防火墙拦了,也可能是域名根本不存在。多打几次 curl -v 对比,比硬背错误码管用。










