根本原因是php的openssl/curl未加载有效ca证书文件,需通过php -r "print_r(openssl_get_cert_locations());"确认default_cert_file和ini_cafile路径是否正确、文件是否存在且可读,并统一配置curl.cainfo与openssl.cafile指向同一最新cacert.pem,同时校准系统时间。

直接告诉你结论:不是 Composer 装不了,是 PHP 的 OpenSSL/cURL 根本没读到有效的 CA 证书文件。所有“SSL certificate verify failed”“error:14090086”“cURL error 60”类报错,95% 都卡在这一步。
先确认 PHP 实际用的证书路径在哪
报错前别急着换证书、改配置、禁 SSL——先让 PHP 自己说话:
运行:php -r "print_r(openssl_get_cert_locations());"
重点看两个字段:
-
default_cert_file:OpenSSL 默认找的 PEM 文件路径 -
ini_cafile:php.ini 中openssl.cafile指向的路径
如果任一为空、为 null、或指向一个不存在/不可读的文件(比如 /etc/ssl/certs/ca-certificates.crt 存在但大小为 0 KB),那就直接导致验证失败。
常见陷阱:
-
ls -l /path/to/file显示权限是777→ PHP 主动拒绝加载 - 路径含中文或空格,却没加双引号(Windows 尤其明显)
- CLI 和 Web SAPI 加载不同
php.ini,而 Composer 只走 CLI 版本
下载并配置最新 cacert.pem
系统自带的 CA 包(如 CentOS 的 ca-certificates 或 Windows ZIP 里的旧 cert.pem)多数已过期,2026 年起无法验证主流 HTTPS 站点。
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
正确做法:
- 去权威源下载最新 PEM:https://curl.se/ca/cacert.pem
- 保存为纯文本文件,确保以 -----BEGIN CERTIFICATE----- 开头,无 HTML、无 BOM、无乱码
- 放到可读路径,例如:
- Linux/macOS:/usr/local/etc/php/cacert.pem
- Windows:C:/php/extras/ssl/cacert.pem(注意用正斜杠或双反斜杠)
证书链顺序必须严格:叶证书 → 中间 CA → 根 CA(自签名根证书放最后)。混入私钥、少一级、顺序颠倒,都会报“链不完整”。
统一配置 openssl.cafile 和 curl.cainfo
Composer 内部可能走 cURL,也可能走 PHP stream context(依赖 OpenSSL),二者证书路径不一致就会“有时行、有时挂”。
打开 CLI 实际生效的 php.ini(运行 php --ini 查 “Loaded Configuration File”):
curl.cainfo = "/usr/local/etc/php/cacert.pem" openssl.cafile = "/usr/local/etc/php/cacert.pem"- Windows 路径含反斜杠必须加双引号:
curl.cainfo = "C:/php/extras/ssl/cacert.pem"
- Linux/macOS 必须用绝对路径,不能写 ~/certs/cacert.pem
- 改完必须重启终端(CLI 环境不会自动 reload)
验证是否生效:php -r "var_dump(openssl_get_cert_locations());",确认 default_cert_file 和 ini_cafile 都指向你刚配的路径,且文件真实可读。
最常被忽略的一点:证书路径对了,但系统时间错得离谱(比如快进到 2030 年或倒退到 2020 年),TLS 握手会直接失败,且不报明确 SSL 错误,只卡在 “Loading…” 或 Connection refused。先 date 或 timedatectl status(Linux/macOS)/ 检查 Windows 时间服务,再折腾证书。










