是系统时间偏差导致的证书过期报错;composer依赖openssl校验证书有效期,本地时间快5分钟或慢2分钟以上即触发“certificate has expired”错误,需先运行date对比标准时间并同步。

确认是不是系统时间偏差导致的证书过期报错
看到 SSL certificate problem: certificate has expired 别急着换证书或关验证,先查时间。Composer 用 OpenSSL 校验证书的 notBefore 和 notAfter,本地时间快 5 分钟或慢 2 分钟以上,就会被当成“证书已过期”。
- 运行
date对比网络标准时间(比如 time1.google.com) - macOS 上执行
sudo sntp -s time.apple.com强制同步(sntp在 Catalina+ 默认可用;若提示 command not found,改用sudo ntpdate -u time.apple.com) - 同步后立刻重试
composer install,很多情况下错误直接消失
检查 PHP 的 OpenSSL 是否启用且证书路径正确
报错 SSL operation failed with code 1 或 certificate verify failed,大概率是 PHP 没读到有效 CA 证书,而不是网络不通。
- 运行
php -m | grep openssl确认扩展已加载;没输出就去php.ini里取消;extension=openssl的注释 - 查证书路径:
php -r "print_r(openssl_get_cert_locations());",重点关注default_cert_file和ini_cafile - 如果路径是
/private/etc/ssl/cert.pem但文件不存在,或 Homebrew 安装了 OpenSSL(如/opt/homebrew/etc/openssl@3/cert.pem),就手动设进去:composer config --global cafile /opt/homebrew/etc/openssl@3/cert.pem - 同时在
php.ini中补上:curl.cainfo = "/opt/homebrew/etc/openssl@3/cert.pem"和openssl.cafile = "/opt/homebrew/etc/openssl@3/cert.pem"
临时绕过 SSL 验证只用于调试,别留着
--no-secure-http 或 config -g secure-http false 不解决证书校验失败本身,它只是让 Composer 允许走 HTTP —— 但 packagist 镜像基本都强制 HTTPS,所以这类命令常无效。真正跳过证书检查得动 PHP 层。
- 单次调试可用:
PHP_SSL_NO_VERIFY=1 composer install(环境变量方式,作用域最小) - 全局禁用风险极高,不推荐:
export PHP_SSL_NO_VERIFY=1再开新终端 - 千万别用
composer config -g disable-tls true:它会退回到纯 HTTP,现在绝大多数镜像已拒绝 HTTP 请求,结果是400 Bad Request或连接重置
切国内镜像 + 清缓存才是稳定组合拳
即使证书和时间都对了,直连 packagist.org 在 macOS 上仍可能因 TLS 握手超时或中间设备干扰失败。阿里云、腾讯云镜像响应更快,且证书链更兼容。
- 设置镜像:
composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/(注意末尾必须有/) - 立刻清缓存:
composer clear-cache;Mac 上还要手动删~/Library/Caches/composer(有时clear-cache不彻底) - 删掉项目里的
composer.lock和vendor/,再跑composer install—— 否则 lock 文件里还记着旧源地址,Composer 会继续往错误路径发请求 - 验证是否生效:
composer install -vvv 2>&1 | head -n 5,看第一行下载 URL 是不是已变成阿里云域名
最常被忽略的是 composer.lock 里硬编码的 provider 地址和 ~/Library/Caches/composer 里残留的元数据,这两处不清,换镜像也白搭。时间、证书、镜像、缓存,四个点里只要漏掉一个,SSL 错误就可能反复出现。











