根本原因是PHP的cURL或OpenSSL扩展找不到、读不了或用了过期CA根证书,需在php.ini中同时配置curl.cainfo和openssl.cafile为同一绝对路径的cacert.pem文件并重启服务,而非禁用SSL验证。

Composer 提示“不安全”或 SSL 证书错误,根本不是 Composer 自己不安全,而是它背后调用的 PHP cURL 或 OpenSSL 扩展找不到、读不了、或用了过期的 CA 根证书文件。修对 php.ini 里的证书路径,90% 的问题当场消失;临时关验证只是掩盖问题,且在 Composer 2.2+ 后 -k 已失效。
怎么确认是证书路径没配好?
别猜,直接运行这两条命令:
-
php --ini—— 看 CLI 模式下实际加载的是哪个php.ini(Web 和 CLI 配置常不同) -
php -r "print_r(openssl_get_cert_locations());"—— 重点看default_cert_file和ini_cafile的值是否为空、路径不存在、或指向一个空文件/老版本(比如 2019 年前的cacert.pem)
如果其中任一字段异常,就是根因。此时 curl -v https://packagist.org/packages.json 也会报同样错误,说明问题在 PHP 层,和 Composer 无关。
php.ini 里必须同时配哪两个配置项?
只设这两个,且路径必须一致、绝对、可读:
curl.cainfo = "/path/to/cacert.pem"openssl.cafile = "/path/to/cacert.pem"
常见踩坑点:
- 路径用了
~或相对路径(./cacert.pem❌),PHP 不识别 - Windows 上单反斜杠
C:phpcacert.pem被解析为转义符,得写成C:/php/cacert.pem或C:\php\cacert.pem - Linux/macOS 下文件权限不对(如
chmod 600),PHP 进程读不到 - 改了
php.ini但没重启 CLI 终端或 Web 服务(php-fpm、Apache、Nginx 都要重载)
证书文件从哪来?怎么放才靠谱?
去官方地址下载最新 Mozilla 根证书包:
- 地址:https://www.php.cn/link/5fe4dadcdb001d8566cd20e6d8a20251
- Linux/macOS 推荐存到:
/usr/local/etc/php/cacert.pem(Homebrew PHP 可能需/usr/local/etc/openssl@3/cert.pem) - Windows(XAMPP/WAMP)推荐存到:
C:/xampp/php/extras/ssl/cacert.pem(注意目录是否存在)
下载后立即验证是否可读:
php -r "var_dump(file_get_contents(ini_get('curl.cainfo')) !== false);"
输出 bool(true) 才算真正就位。
为什么 composer config --global cafile 不起作用?
这个命令只影响 Composer 自己封装的 HTTP 客户端(基于 php-http),而绝大多数 SSL 报错发生在底层 cURL 或 OpenSSL 扩展层——它们完全无视 Composer 的配置。你看到的 cURL error 60 或 SSL certificate problem: unable to get local issuer certificate,都是扩展抛出的,不是 Composer 逻辑层的问题。
同理,composer config -g secure-http false 会让所有源降级走 HTTP,但 Packagist 自 2022 年起已强制 HTTPS,实际会直接失败;而且这会暴露认证凭据,绝不能用于 CI 或团队环境。
真正该盯住的,永远是 php -i | grep -E 'curl.cainfo|openssl.cafile' 的输出是否匹配你刚写的路径——其他都是障眼法。











