composer ssl握手失败主因是openssl版本过低(如1.0.2k及以下)或ca证书路径配置错误;需通过openssl version -a和openssl_get_cert_locations()确认,并统一配置curl.cainfo与openssl.cafile为权威cacert.pem绝对路径。

Composer安装卡在SSL握手失败,基本不是网络问题,而是你本地的OpenSSL版本太老或CA证书路径没配对。 临时关SSL验证(比如--no-secure-http)能绕过报错,但掩盖了根本风险——下次连私有仓库或Git API也会崩。得从PHP底层的证书信任链动手。
怎么确认是OpenSSL版本过低还是证书路径错了
别凭错误信息猜,直接看PHP自己认不认证书:
- 运行
openssl version -a,如果输出里含1.0.2k或更低,基本锁死——Packagist自2023年起只认TLS 1.2+,而OpenSSL 1.0.x根本不支持 - 执行
php -r "print_r(openssl_get_cert_locations());",重点盯default_cert_file和ini_cafile两个字段:路径为空、文件不存在、或文件大小<100KB(说明是空包或旧版bundle),就是证书路径失效 - 再补一刀:
curl -v https://packagist.org/packages.json,如果也报SSL certificate problem: unable to get local issuer certificate,说明问题出在系统/PHP层,不是Composer配置问题
Windows下php.ini里的curl.cainfo和openssl.cafile必须同时配且路径一致
Windows用户最容易在这儿翻车:改了一个、路径写错、或者用了CLI的php.ini但Web服务跑的是另一份。关键点就三个:
- 证书文件必须从权威源下载:
https://curl.se/ca/cacert.pem,存成绝对路径,比如C:/php/extras/ssl/cacert.pem - 在php.ini里写两行,且值完全一样、带双引号、用正斜杠或双反斜杠:
curl.cainfo="C:/php/extras/ssl/cacert.pem"和openssl.cafile="C:/php/extras/ssl/cacert.pem" - 改完立刻跑
php --ini确认编辑的是当前CLI生效的php.ini,然后php -i | grep -i "curl.cainfo"验证是否已加载新值——不重启终端,新配置不会生效
Linux/macOS别迷信/etc/ssl/certs/ca-certificates.crt
很多发行版的/etc/ssl/certs/ca-certificates.crt是空链接或权限为000,PHP读不了。Homebrew PHP更常直接忽略它。稳妥做法是:
- 下载证书到固定位置:
sudo curl -o /usr/local/etc/php/cacert.pem https://curl.se/ca/cacert.pem - 只在php.ini里配
curl.cainfo="/usr/local/etc/php/cacert.pem"(openssl.cafile可不设,cURL优先级更高) - 确保PHP进程有读权限:
sudo chmod 644 /usr/local/etc/php/cacert.pem - macOS用Homebrew PHP记得重启服务:
brew services restart php;Linux上如果是php-fpm,要sudo systemctl restart php-fpm
最常被忽略的一点:Docker容器里即使装了ca-certificates包,也可能没更新证书数据库——update-ca-certificates这步不能跳。Alpine镜像尤其要小心,默认不带完整CA包,光apk add ca-certificates不够,还得update-ca-certificates手动刷新。











