先确认是系统时间偏差而非CA证书失效;90%的“certificate has expired”错误源于本地时间快慢超3–5分钟,需先校准系统时间,再验证并更新PHP的CA证书路径配置。

先确认是系统时间偏差还是CA证书失效
报 SSL certificate problem: certificate has expired 时,90%不是证书真过期,而是本地系统时间快了或慢了超过3–5分钟。PHP 的 OpenSSL 会用系统时间比对证书的 notBefore 和 notAfter 字段,一旦越界就直接拒绝握手。
别急着改证书,先运行:date
对比当前真实时间(比如用手机或 time.gov)。若偏差明显(尤其 Windows 虚拟机、Docker 容器、某些 macOS 虚拟化环境),执行校准:
- Linux/macOS:
sudo ntpdate -s time.apple.com或sudo systemctl restart systemd-timesyncd - Windows:右键任务栏时间 → “调整日期和时间” → 开启“自动设置时间”
- Docker 容器:加
--privileged并挂载主机时钟(/etc/localtime:/etc/localtime:ro)或在启动命令里加ntpd -g -q
校准后再试 composer install,如果错误消失,问题就在这儿——后续可加 cron 或 healthcheck 防复发。
验证PHP是否加载了有效的CA证书路径
运行 php -r "print_r(openssl_get_cert_locations());",重点看输出里的 default_cert_file 和 ini_cafile:
- 如果值为空、路径不存在、文件大小 ≤ 1KB,说明 PHP 根本没读到证书
- 如果路径存在但最后修改时间早于 2023 年(比如还用着 2019 年的 bundle),大概率缺 ISRG Root X1,无法验证 Let’s Encrypt 新签发的站点(含 packagist.org 和所有主流镜像)
- 运行
php --ini确认你编辑的是 CLI 模式下真正生效的php.ini,不是 Apache 或 FPM 的那个
别依赖系统自带路径(如 /etc/pki/tls/cert.pem),很多发行版这个文件是空链接或已过期。直接下载最新权威 CA 包:curl -o /usr/local/etc/php/cacert.pem https://curl.se/ca/cacert.pem(Linux/macOS)curl -o C:/php/extras/ssl/cacert.pem https://curl.se/ca/cacert.pem(Windows)
必须同时配置 curl.cainfo 和 openssl.cafile
只设其中一个,PHP 底层不同组件仍可能走另一套路径,导致部分请求成功、部分失败(比如 composer install 卡在 download,但 composer diagnose 显示正常)。
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
在 CLI 生效的 php.ini 中添加(注意:必须是绝对路径,不能用 ~ 或相对路径):
-
curl.cainfo="/usr/local/etc/php/cacert.pem"(Linux/macOS)或curl.cainfo="C:/php/extras/ssl/cacert.pem"(Windows) -
openssl.cafile="/usr/local/etc/php/cacert.pem"(同上,路径完全一致) - Windows 下路径含空格或反斜杠时,务必加英文双引号,例如:
curl.cainfo="C:/php/extras/ssl/cacert.pem"
改完保存,**关闭当前终端再新开一个**——CLI 模式下 PHP 不会热重载 ini 配置,靠重启进程生效。
别信 composer config --global cafile
这条命令写入的是 ~/.composer/config.json,只影响 Composer 自己封装的 HTTP 请求(比如主流程下载包),但以下环节仍绕不开 PHP 底层配置:
- 解析
composer.json中自定义仓库 URL 时的 HTTPS 校验 - 验证
composer.lock签名时的 OpenSSL 调用 - Docker CI 环境、Webhook 触发的部署脚本中根本不会加载用户级配置
如果你在 GitHub Actions、GitLab CI 或容器里跑 composer install,cafile 配置基本无效。必须通过挂载证书文件 + 修改容器内 php.ini,或用 ENV 变量指定路径(如 PHP_INI_SCAN_DIR 加载额外 ini)来落地。

















