根本原因是php底层openssl信任的根证书过期,无法验证isrg root x1证书;应通过php -r"print_r(openssl_get_cert_locations());"确认default_cert_file路径,下载curl.se最新cacert.pem并配置php.ini中openssl.cafile和curl.cainfo指向该文件,重启php生效。

composer 报 “SSL certificate problem: certificate has expired” 不是镜像源坏了,也不是 Composer 本身要升级,而是 PHP 底层 OpenSSL 信任的根证书太旧,无法验证 Let’s Encrypt 的 ISRG Root X1 证书(DST Root CA X3 已于 2021 年 9 月过期)。修错地方,换镜像、关验证都白搭。
怎么确认真是 CA 证书问题,而不是网络或镜像宕机?
别猜,用三行命令快速定位:
-
php -r "print_r(openssl_get_cert_locations());"—— 看default_cert_file路径是否存在、文件是否为空或最后修改时间早于 2022 年 -
curl -I https://packagist.org—— 如果也报SSL certificate problem: unable to get local issuer certificate,说明系统级证书已失效 -
php --ini—— 确认你改的是 CLI 模式真正生效的php.ini(尤其 Docker / phpEnv / 多版本 PHP 环境里常有多个)
Windows 用户最常踩的 php.ini 配置坑
XAMPP/WAMP/phpEnv 自带的 cacert.pem 基本停更于 2021 年,且 curl.cainfo 和 openssl.cafile 必须同时设、路径完全一致,否则仍报错:
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
- 下载最新
cacert.pem(来源必须是 curl.se 官方),存到如C:/php/extras/ssl/cacert.pem - 在
php.ini中写两行,路径用正斜杠或双反斜杠:curl.cainfo="C:/php/extras/ssl/cacert.pem"openssl.cafile="C:/php/extras/ssl/cacert.pem" - 改完必须关闭并重开终端——CLI PHP 不热加载 ini;Web 环境必须重启 Apache/Nginx/PHP-FPM,光 reload 不行
Linux/macOS 更新系统级 CA 证书更彻底
系统级更新比单独配 php.ini 更可靠,尤其对 Docker 和 CI 环境:
- Debian/Ubuntu:
sudo apt update && sudo apt install --reinstall ca-certificates && sudo update-ca-certificates - macOS + Homebrew:
brew update && brew upgrade openssl@3 && brew reinstall ca-certificates,再检查php -r "print_r(openssl_get_cert_locations());"中capath是否指向 Homebrew 的证书目录 - Docker 构建时:在
Dockerfile中加RUN apt-get update && apt-get install -y ca-certificates && rm -rf /var/lib/apt/lists/*
为什么 composer config -g cafile 或 secure-http false 大概率无效?
这些命令不触达底层 cURL/OpennSSL 的证书加载逻辑:
-
composer config -g cafile只影响 Composer 自封装的 HTTP 客户端(如 php-http 驱动),而实际报cURL error 60的是 PHP 内置 cURL 扩展 -
secure-http false不是跳过证书校验,只是允许非 HTTPS 源,反而让所有仓库降级走 HTTP,暴露凭证和包完整性风险 - 真正起效的只有
php.ini中的curl.cainfo和openssl.cafile,且必须指向同一有效文件
cURL 和 OpenSSL 扩展各自读一个配置项,路径稍有不一致或格式错误(比如 Windows 单反斜杠被当转义符、路径含空格未加引号),就会静默失败。验证时别只看 composer diagnose,一定要跑 php -r "print_r(openssl_get_cert_locations());" 看 PHP 实际加载的是哪个文件。










