根本原因是php openssl找不到可信根证书或系统时间偏差超2分钟导致证书校验失败;需运行php -r "print_r(openssl_get_cert_locations());"确认default_cert_file和ini_cafile路径有效,并在cli生效的php.ini中同步配置curl.cainfo与openssl.cafile指向同一最新cacert.pem绝对路径,同时校准系统时钟。

根本原因不是网络差或镜像挂了,而是 PHP 的 OpenSSL 在 TLS 握手时卡死——它找不到可信根证书,或者系统时间偏差太大,导致证书有效期校验失败。修对 php.ini 里的证书路径,或校准系统时钟,95% 的问题当场消失。
怎么确认是 CA 证书路径没配对
别猜,让 PHP 自己说:php -r "print_r(openssl_get_cert_locations());"。重点看 default_cert_file 和 ini_cafile 两个值:
- 为空、路径不存在、文件大小不到 200KB(旧版 cacert.pem 通常只有几十 KB),就是它了
-
curl -v https://packagist.org/packages.json 2>&1 | grep "SSL certificate"如果也报unable to get local issuer certificate,说明是底层证书链问题,不是 Composer 配置错 -
php --ini看清楚你改的php.ini是不是 CLI 模式下真正生效的那个(Docker、phpEnv、多版本 PHP 常有多个)
Windows/macOS/Linux 统一修复证书路径
必须同时设置两个参数,且指向同一绝对路径的最新 cacert.pem:
工作流任务拆解与模型编排技能。使用场景:(1) 收到复杂工作任务需要拆解为可执行步骤,(2) 需要为不同步骤选择最合适的模型,(3) 需要跟踪工作流进度和模型使用情况,(4) 长时间任务卡住需要问题诊断和解决方案。
- 从 https://www.php.cn/link/5fe4dadcdb001d8566cd20e6d8a20251 下载最新证书,保存到稳定位置(如
C:/php/extras/ssl/cacert.pem或/usr/local/etc/php/cacert.pem) - 在 CLI 生效的
php.ini中添加(注意:路径必须用正斜杠或双反斜杠,Windows 下带空格或中文路径要加引号):curl.cainfo="/path/to/cacert.pem"<br>openssl.cafile="/path/to/cacert.pem"
- 改完保存,关掉当前终端再新开一个——CLI 下不需要重启 Apache/Nginx,但必须重载 PHP 配置上下文
- 验证:
php -r "var_dump(ini_get('curl.cainfo'));"输出必须是你刚写的路径
系统时间偏差超过 2 分钟也会触发 SSL 失败
证书有明确的 notBefore 和 notAfter 时间戳,本地时间快 5 分钟或慢 3 分钟,OpenSSL 就直接拒绝握手:
- Linux/macOS:
timedatectl status | grep "System clock synchronized",输出yes才算正常;否则运行:sudo timedatectl set-ntp true<br>sudo systemctl restart systemd-timesyncd
- Windows(管理员 CMD):
w32tm /resync<br>w32tm /config /syncfromflags:manual /manualpeerlist:"time.nist.gov pool.ntp.org"<br>w32tm /resync
- 偏差 > 2 分钟必须修复,临时禁用 SSL 验证(如
COMPOSER_DISABLE_TLS=1)只适合调试,不解决根本问题
最常被忽略的是:改完 php.ini 后没关终端重开,或者在 Docker/CI 环境里压根没挂载新证书文件——php -r "print_r(openssl_get_cert_locations());" 这一行命令,得在目标环境里真跑一遍才算数。










