答案是php底层openssl/curl无法验证证书,因系统时间偏差超±2分钟或ca证书文件缺失/过期;需先校准时间、再用php -r确认证书路径并更新为最新cacert.pem,同时配置php.ini中curl.cainfo和openssl.cafile为同一绝对路径。

证书不匹配不是镜像或 Composer 本身的问题,而是 PHP 底层 OpenSSL 或 cURL 扩展在验证 HTTPS 证书时找不到可信根证书,或者系统时间偏差过大导致证书有效期校验失败。真正在报错的不是“证书错了”,是“PHP 不认识这个证书”。
确认是不是系统时间偏差导致的
执行 date 查看当前系统时间,再访问 time.is 对比。若偏差超过 ±2 分钟,SSL certificate problem: certificate has expired 就是典型表现——证书没过期,你的时间错了。
- Linux/macOS:运行
sudo timedatectl set-ntp true并重启服务sudo systemctl restart systemd-timesyncd,再用timedatectl status | grep "System clock synchronized"确认输出为yes - Windows(管理员 CMD):先
net start w32time,再w32tm /resync;若仍不准,加一句w32tm /config /syncfromflags:manual /manualpeerlist:"time.nist.gov pool.ntp.org" - 容器或 CI 环境里,
systemd-timesyncd常被禁用,得手动apk add openntpd && ntpd -q(Alpine)或挂载 host 时间(-v /etc/localtime:/etc/localtime:ro)
检查 PHP 是否加载了有效的 CA 证书文件
运行 php -r "print_r(openssl_get_cert_locations());",重点看 ini_cafile 和 default_cert_file 两个字段:
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
- 如果为空、路径不存在、或文件大小为 0,说明 PHP 根本没读到证书
- 如果路径存在但最后修改时间早于 2022 年(比如停更的
curl-ca-bundle.crt),就得换新证书 - 下载最新证书:
curl -sS https://curl.se/ca/cacert.pem -o /usr/local/etc/php/cacert.pem(macOS/Linux)或curl -sS https://curl.se/ca/cacert.pem -o C:/php/extras/ssl/cacert.pem(Windows) - 在 CLI 模式生效的
php.ini中同时写入两行(路径必须是绝对路径、英文双引号):curl.cainfo = "/usr/local/etc/php/cacert.pem"openssl.cafile = "/usr/local/etc/php/cacert.pem" - 改完必须关掉当前终端,新开一个再测试;Web 环境需重启
php-fpm或apache
为什么 composer config -g cafile 经常没用
这条命令只影响 Composer 自己封装的 HTTP 客户端(基于 php-http),但实际发起 HTTPS 请求的是 PHP 的 cURL 或 OpenSSL 扩展——它无法覆盖 curl.cainfo 的优先级,也不能修复底层 TLS 握手失败。
- 执行后显示 “CA file configured”,但
composer install依然报错,就是典型失效表现 - 它对
git clone、插件安装、或任何绕过 Composer HTTP 客户端的操作完全无效 - 仅当
php.ini真没法改时,可临时兜底:composer config -g cafile "/path/to/cacert.pem"
镜像源配置错误也会伪装成证书问题
比如配了阿里云镜像但 URL 少了末尾斜杠:https://mirrors.aliyun.com/composer → 实际请求变成 /composerpackages.json(404),部分旧版 Composer 会 fallback 到 HTTPS 错误提示,误导你去修证书。
- 项目级配置比全局更可靠:
composer config repo.packagist composer https://mirrors.aliyun.com/composer/(注意结尾/) - 键名必须是
repo.packagist,不能是repos.packagist或repositories.packagist - type 必须显式写
composer,漏掉则整个配置被忽略 - 验证是否生效:
composer config -g repo.packagist输出应为完整 JSON:{"type": "composer", "url": "https://mirrors.aliyun.com/composer/"}
真正卡住的地方往往不是“该不该换证书”,而是 PHP CLI 和 Web 模式用了不同 php.ini、改了却没重启进程、或者证书路径用了单反斜杠导致 Windows 下解析失败——这些细节不验证,光重装 Composer 或换镜像都没用。










