根本原因是PHP的OpenSSL/cURL扩展缺失或无法读取有效CA证书,必须在php.ini中正确配置openssl.cafile和curl.cainfo为同一绝对路径的cacert.pem,启用openssl扩展,并验证php -r "print_r(openssl_get_cert_locations());"输出一致。

直接结论:这不是 Composer 的错,是 PHP 底层 OpenSSL/cURL 找不到或读不懂有效的 CA 证书文件。修它必须改 php.ini,不是改 Composer 配置。
检查 openssl 扩展是否真启用、证书路径是否被加载
很多人以为开了 extension=openssl 就万事大吉,其实 CLI 和 Web 环境可能用的是两份 php.ini,且路径配置可能根本没生效。
- 运行
php --ini确认当前 CLI 用的是哪个php.ini - 运行
php -m | grep openssl看输出里有没有openssl—— 没有就回去开扩展 - 运行
php -i | grep -E "(openssl.cafile|curl.cainfo)",看两行值是不是非空、是不是同一个绝对路径 - 特别注意 Windows 下写成
C:phpcacert.pem会被当转义符处理,必须写C:/php/cacert.pem或C:\php\cacert.pem
下载并配置正确的 cacert.pem 文件
系统自带的证书(比如 Ubuntu 的 /etc/ssl/certs/ca-certificates.crt 或 XAMPP 自带的老包)大概率已过期。必须用官方最新版。
- 从 https://www.php.cn/link/cd6a3674478af373087f891eeb390100 下载 —— 别用旧页面或第三方镜像
- 保存为稳定绝对路径,例如:
/usr/local/etc/php/cacert.pem(macOS/Linux)或C:/php/cacert.pem(Windows) - 在
php.ini中同时设置两项,路径一字不差:openssl.cafile="/usr/local/etc/php/cacert.pem"curl.cainfo="/usr/local/etc/php/cacert.pem" - 改完重启终端(CLI 不读缓存),再跑
php -r "print_r(openssl_get_cert_locations());"验证default_cert_file和ini_cafile是否一致且指向真实文件
别信 composer config -g cafile 或 disable-tls
这些命令对 Composer 默认 HTTP 客户端基本无效,因为底层还是走 PHP 的 stream_context_create() 或 cURL,证书校验由它们控制。
-
composer config -g cafile "/path/to/cacert.pem"只影响部分 HTTP 驱动(如 php-http),不能修复file_get_contents()或原生 cURL 报的certificate verify failed -
composer config -g disable-tls true是彻底关掉 HTTPS 强制要求,之后所有包走 HTTP,中间人攻击风险拉满 —— 不是修复,是裸奔 -
composer require --no-secure-http同样只绕开协议强制,不解决证书链验证失败这个根因
镜像源不能代替证书修复
阿里云、腾讯云、Laravel China 镜像都是 HTTPS 的,一样要过证书验证。切镜像只是换了个域名,不解决 CA 文件缺失问题。
- 如果切了镜像还报错,说明证书问题仍在;如果切了就不报了,大概率是原域名(packagist.org)被中间设备劫持或 DNS 污染,不是证书问题
- 可临时用
curl -I https://mirrors.aliyun.com/composer/测试 —— 若也失败,100% 是本地 PHP 证书环境故障 - 镜像只应作为网络稳定性补充,不该当成 SSL 问题的解药
最常被忽略的一点:改完 php.ini 后没确认 openssl_get_cert_locations() 输出是否真的变了。很多人改了路径、重启了 Apache,但 CLI 还在读旧 ini,或者路径里多打了个空格、少了个引号,导致配置静默失效。











