根本原因是PHP未正确加载有效CA证书文件,需通过php -r "print_r(openssl_get_cert_locations());"确认curl.cainfo和openssl.cafile路径,下载最新cacert.pem并统一配置两处为同一绝对路径,重启环境后验证生效。

Composer 报 SSL 证书过期或“unable to get local issuer certificate”,不是证书真过期了,而是 PHP 根本没读到有效的 CA 证书文件——curl.cainfo 或 openssl.cafile 指向空、损坏、路径错,或文件本身太旧。修复必须落在 PHP 配置层,而非 Composer 命令行参数。
怎么确认是 CA 文件路径失效
先跑这行命令,看 PHP 实际信任的证书位置:
php -r "print_r(openssl_get_cert_locations());"
重点检查两个字段:
-
default_cert_file:PHP 默认尝试加载的路径,如果为空、指向不存在的文件、或文件大小为 0(ls -l /path/to/file),就是它了 -
ini_cafile:来自 php.ini 的显式配置,如果和default_cert_file不一致,说明 php.ini 修改未生效或加载了错误的配置文件
再补一刀验证:
curl -v https://packagist.org/packages.json
如果同样报 SSL certificate problem,说明是整个 PHP/cURL 层级的信任链断了,不是 Composer 独有问题。
Windows 下改 php.ini 必须注意的三件事
Windows 环境(XAMPP/WAMP/MAMP)最容易栽在这几个细节上:
- 路径必须用正斜杠
/或双反斜杠\,单反斜杠会被 PHP 当作转义符,导致路径解析失败 - 别用 PHP 自带的
curl-ca-bundle.crt——它常年不更新,2024 年后基本失效;应下载最新cacert.pem(来自 curl.se/ca/cacert.pem)并存到稳定路径,如C:/php/extras/ssl/cacert.pem - php.ini 必须同时设两行,且路径完全一致:
curl.cainfo = "C:/php/extras/ssl/cacert.pem"<br>openssl.cafile = "C:/php/extras/ssl/cacert.pem"
改完后,CLI 模式要关掉当前终端、新开一个;Web 模式(Apache/Nginx)必须重启整个服务,光重载配置没用。
composer config --global cafile 是最干净的长期方案
Composer 2.2+ 原生支持该配置,优先级高于 PHP 的 curl.cainfo,且只影响 Composer 自身请求,不波及其他 PHP 应用:
- 先确认系统级 CA 文件存在:Linux/macOS 执行
ls -l /etc/ssl/certs/ca-certificates.crt,macOS Homebrew PHP 通常是/opt/homebrew/etc/ca-certificates/cert.pem - 写入全局配置:
composer config --global cafile /etc/ssl/certs/ca-certificates.crt - 验证是否生效:
composer diagnose输出中应明确显示CA file: /etc/ssl/certs/ca-certificates.crt并标为 OK
这个配置不会影响 file_get_contents('https://...') 或其他扩展行为,只管 Composer 的 HTTPS 请求,适合多项目共用同一套 PHP 环境但证书策略不同的场景。
别碰 COMPOSER_DISABLE_TLS=1,除非你清楚后果
临时关闭 TLS 验证(如 COMPOSER_DISABLE_TLS=1 composer install)只应在离线构建机、CI 流水线无外网、或已确认中间代理强制解密 HTTPS 的极少数场景下使用:
- 它让所有 Composer 请求降级为明文 HTTP,等同于把包名、版本、依赖关系全暴露在链路上
- 一旦固化在脚本或 CI 配置里,极易被遗忘,后续上线即成安全漏洞
- 它无法解决
cURL error 35(TLS 握手失败)或connection reset by peer(协议不兼容),这些是更底层的问题,关 TLS 反而掩盖真实原因
真正卡在握手阶段时,composer diagnose 的 HTTPS connectivity 会直接标 ERROR,此时应查 OpenSSL 版本、TLS 协议支持、或企业代理策略,而不是急着关验证。


















