php 8.0+ 下 https 请求证书错误必须同时禁用证书链和主机名验证:curl 需设 curlopt_ssl_verifypeer=false 且 curlopt_ssl_verifyhost=0;file_get_contents 需在 stream_context_create 中设 'verify_peer'=>false 和 'verify_peer_name'=>false,缺一不可。

PHP 8.0 下用 file_get_contents() 或 curl_exec() 下载 HTTPS 文件时遇到证书错误,不能靠“关掉某个开关”解决——必须显式禁用验证逻辑,且两个关键选项缺一不可。
curl_setopt 必须同时设 CURLOPT_SSL_VERIFYPEER 和 CURLOPT_SSL_VERIFYHOST
只关 CURLOPT_SSL_VERIFYPEER 会导致域名校验仍失败;只关 CURLOPT_SSL_VERIFYHOST 则证书链验证照常报错。PHP 7.4+ 默认开启 verify_peer_name,不配对关闭会直接连接中断。
-
CURLOPT_SSL_VERIFYPEER设为false:跳过 CA 证书链验证 -
CURLOPT_SSL_VERIFYHOST设为0(整数零,不是布尔false):关闭主机名匹配检查(2是严格模式,1已被忽略) - 二者必须一起设置,否则行为不确定,尤其在 PHP 8.0+ 中更容易触发
SSL certificate problem错误
stream_context_create 中 ssl.verify_peer 和 verify_peer_name 都要 false
当你用 file_get_contents('https://...') 或 fopen('https://...', 'r') 时,cURL 不生效,得走流上下文。这里参数名和 cURL 不同,但逻辑一致:漏掉任一个都会失败。
-
'verify_peer' => false:等效于CURLOPT_SSL_VERIFYPEER -
'verify_peer_name' => false:等效于CURLOPT_SSL_VERIFYHOST = 0,不是true或1 - 不要试图用
ini_set('openssl.cafile', '')“清空”配置——这不会跳过验证,反而让 OpenSSL 回退到不可控的默认路径
为什么 openssl.cafile / curl.cainfo 不能用来“跳过”验证
这两个 php.ini 配置项是用于指定可信 CA 证书路径的,不是开关。设为空、null 或不存在的路径,只会让验证失败得更早(比如 error:140AB18F:SSL routines:SSL_CTX_use_certificate_chain_file:ee key too small),不会绕过校验。
-
openssl.cafile影响file_get_contents()、openssl_x509_parse()等函数 -
curl.cainfo只影响 cURL 请求,和流上下文无关 - 它们的作用是“告诉 PHP 用哪份证书去验证”,不是“要不要验证”
最易被忽略的一点:PHP 8.0+ 对 verify_peer_name 的默认值更严格,即使你没显式设它,在流上下文中也会默认为 true;而 cURL 的 CURLOPT_SSL_VERIFYHOST 在 PHP 8.2+ 已标记为废弃,但设成 0 仍有效——别信文档里“已废弃就不用管”的说法,该设还得设。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











