答案是运行php -r "print_r(openssl_get_cert_locations());"并检查default_cert_file和ini_cafile:若为空、路径不存在或文件≤10KB即为OpenSSL配置问题;再用curl -v验证是否同样报SSL证书错误,可排除网络及镜像故障。

怎么确认是 OpenSSL 配置问题,不是网络或镜像故障
别看错误里有没有“SSL”“certificate”字眼,直接让 PHP 自己说:运行 php -r "print_r(openssl_get_cert_locations());"。重点盯 default_cert_file 和 ini_cafile 两个字段——如果为空、路径不存在、或对应文件大小 ≤ 10KB(说明是空包或旧版 bundle),就是它了。
再补一刀:curl -v https://packagist.org/packages.json。如果也报 SSL certificate problem: unable to get local issuer certificate,说明问题出在 PHP/cURL 层,跟 Composer 镜像、代理、DNS 全都无关。
Windows 用户尤其容易误判:XAMPP/WAMP 自带的 curl-ca-bundle.crt 多数停更于 2021 年,文件存在但内容过时,file_get_contents() 能读,openssl 却拒绝验证——得看实际内容是否含现代根证书(比如 ISRG Root X1)。
Windows 下 php.ini 必须同时配对的两个配置项
只改 curl.cainfo 或只改 openssl.cafile 都没用。PHP 在不同场景下会分别读取这两个值,缺一就 fallback 到空信任链。
- 下载最新证书:
curl -sS https://curl.se/ca/cacert.pem -o C:/php/extras/ssl/cacert.pem(路径必须存在,建议先手动建好C:/php/extras/ssl/目录) - 编辑 CLI 模式真正生效的
php.ini(先跑php --ini确认Loaded Configuration File路径) - 在文件末尾加两行,路径用正斜杠、带双引号、绝对路径:
curl.cainfo = "C:/php/extras/ssl/cacert.pem"openssl.cafile = "C:/php/extras/ssl/cacert.pem" - 改完必须关掉当前终端、新开一个——CLI 模式不重启终端,新配置不生效
Linux/macOS 上别信 /etc/ssl/certs/ca-certificates.crt
很多发行版的 /etc/ssl/certs/ca-certificates.crt 是空链接、权限为 000,或指向一个已删的文件。PHP 读不了,就会静默 fallback 到无证书状态。
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 优先级更高) - 确保可读:
sudo chmod 644 /usr/local/etc/php/cacert.pem - macOS Homebrew 用户记得重启服务:
brew services restart php
为什么 composer config -g cafile 总是不起作用
这条命令只写进 ~/.composer/config.json,只影响 Composer 自己封装的 HTTP 客户端(基于 php-http)。但实际发起 HTTPS 请求的是 PHP 的 cURL 或 OpenSSL 扩展——它完全不读这个配置。
典型表现:composer diagnose 显示 “CA file configured”,但 composer install 依然报 cURL error 60 或 SSL connect error。
一旦涉及 Git 克隆、插件调用、或某些扩展直连 HTTPS,还是会走 PHP 原生 TLS 栈,绕不开 php.ini 配置。临时应急可用 COMPOSER_CAFILE 环境变量,但长期必须修底层。


















