根本原因是php的curl或openssl找不到、读不了或证书过期;运行php -r "print_r(openssl_get_cert_locations());"查看default_cert_file和ini_cafile是否为空、路径无效或文件大小为0,再用curl -v https://packagist.org/packages.json验证是否同样报错,即可确认是证书路径问题而非网络或代理。

根本不是 Composer 本身的问题,而是 PHP 的 cURL 或 OpenSSL 找不到、读不了或证书过期了——关 TLS 只是掩盖问题,修对 curl.cainfo 或 openssl.cafile 才算真正解决。
怎么确认是证书路径问题,而不是网络或代理?
别猜,直接让 PHP 自己说话:
- 运行
php -r "print_r(openssl_get_cert_locations());",重点看default_cert_file和ini_cafile字段值 - 如果为空、路径不存在、文件大小为 0(比如只有几 KB),基本就是它了
- 再补一刀:
curl -v https://packagist.org/packages.json—— 如果 curl 同样报SSL certificate problem: unable to get local issuer certificate,说明问题出在系统/PHP 层,不是 Composer 配置
Windows 下配 curl.cainfo 最容易踩的坑
不是证书没下载,而是路径写错了或没生效:
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
- 下载
cacert.pem后推荐固定存到C:\php\extras\ssl\cacert.pem(哪怕 PHP 装在其他盘) - 在
php.ini里写路径时用了单反斜杠C:\php\extras\ssl\cacert.pem却没加双引号,PHP 解析失败;必须写成curl.cainfo="C:\php\extras\ssl\cacert.pem"或curl.cainfo="C:/php/extras/ssl/cacert.pem" - 改了 CLI 的
php.ini,但 Web 环境(如 Apache)用的是另一个 —— 务必先跑php --ini确认你正在编辑的是哪个文件 - 改完没重启终端或服务,
php -i | grep curl.cainfo还显示旧值
Linux/macOS 下为什么 /etc/ssl/certs/ca-certificates.crt 常常不生效?
不是文件不存在,而是 PHP 不认它:
- 某些发行版里它是空链接,PHP 读不了;Homebrew PHP 更常完全忽略系统证书路径
- 正确做法:下载权威证书包:
curl -o /usr/local/etc/php/cacert.pem https://curl.se/ca/cacert.pem - 在
php.ini中只写一行:curl.cainfo="/usr/local/etc/php/cacert.pem"(路径必须绝对,且确保 PHP 进程有读权限) - Mac 上若用 Homebrew PHP,执行
brew services restart php;Linux 上重启php-fpm或apache2 - 验证:
php -r "var_dump(ini_get('curl.cainfo'));"输出应是你刚写的路径
为什么 composer config --global cafile 基本没用?
这条命令只影响 Composer 自己封装的 HTTP 客户端,绕不过 PHP 底层的 cURL/SSL 验证逻辑:
- 它不会修改
curl.cainfo,也不会让file_get_contents('https://...')突然变正常 - 如果你发现设了
cafile后composer diagnose还提示 “CA bundle not found”,说明 PHP 层根本没加载证书 - 真正起效的优先级是:
curl.cainfo>openssl.cafile> Composer 的cafile配置
最常被忽略的一点:改完 php.ini 后,CLI 模式下必须关闭当前终端重开,否则 PHP 进程仍缓存旧配置;Web SAPI 则必须重启对应服务。证书路径写对了,但没重载上下文,等于白配。










