PHP HTTPS请求失败的根本原因是OpenSSL和cURL找不到有效CA证书;需运行php -r "print_r(openssl_get_cert_locations());"确认default_cert_file和ini_cafile路径,同时配置php.ini中openssl.cafile与curl.cainfo为同一最新cacert.pem绝对路径并重启服务。

根本不是 Composer 自己的证书过期,而是 PHP 底层 OpenSSL 和 cURL 扩展找不到或加载了失效的 CA 证书文件——所有 HTTPS 请求(包括访问 packagist.org、阿里云镜像、腾讯云镜像)都会失败,报错如 error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed 或 cURL error 60。
怎么确认 PHP 实际用的证书路径
别猜路径,让 PHP 自己说:
运行 php -r "print_r(openssl_get_cert_locations());",重点看两个字段:
-
default_cert_file:PHP 默认尝试读的路径,为空、不存在、或文件大小为 0 就是病灶 -
ini_cafile:来自 php.ini 的显式配置,如果和default_cert_file不一致,说明配置没生效或加载了错误的 php.ini
常见失效路径包括:/etc/ssl/certs/ca-certificates.crt(旧版 Ubuntu)、C:/php/extras/ssl/cacert.pem(XAMPP/WAMP 自带的老包)、/usr/local/etc/php/cacert.pem(Homebrew PHP 未更新时)。
openssl.cafile 和 curl.cainfo 必须同时设、路径完全一致
Composer 底层依赖 PHP 的 OpenSSL 层(如 file_get_contents)和 cURL 层(默认 HTTP 客户端),两者各自读一个配置项:
-
openssl.cafile控制 OpenSSL 层 -
curl.cainfo控制 cURL 层
只配一个?大概率仍有报错;路径写错(比如漏 .pem、用相对路径、Windows 下单反斜杠被当转义符)?照样失败。
正确做法:
- 从 curl.se 官方 下载最新
cacert.pem - 存到稳定绝对路径,例如:
/usr/local/etc/php/cacert.pem(Linux/macOS)或C:/php/extras/ssl/cacert.pem(Windows) - 在 php.ini 中写两行,路径必须一模一样:
openssl.cafile="/usr/local/etc/php/cacert.pem"<br>curl.cainfo="/usr/local/etc/php/cacert.pem"
- Windows 路径务必用正斜杠
/或双反斜杠\,别用单反斜杠
别信 composer config --global cafile
很多人试过 composer config -g cafile "/path/to/cacert.pem",但依然报错——因为该配置只影响 Composer 自封装的 HTTP 客户端(如 php-http 驱动),而实际触发 cURL error 60 或 certificate verify failed 的是底层 cURL 或 stream 扩展,根本不走这个配置。
验证是否生效最直接的方式是跑:php -r "echo file_get_contents('https://packagist.org/packages.json') ?: 'fail';"。如果还 fail,说明 PHP 层证书配置没到位,别再折腾 Composer 配置了。
最容易被忽略的是:PHP CLI 和 Web 服务器可能加载不同的 php.ini。执行 php --ini 和 php -i | grep 'Loaded Configuration File' 确认 CLI 加载的是哪个文件;如果用的是 Docker、Laravel Sail、或 WAMP/XAMPP,很可能 CLI 和 Apache/Nginx 用的不是同一份配置。











