卡在“Resolving dependencies”是SAT求解器暴力回溯版本冲突所致,非网络问题;卡在“Downloading”则多因TLS握手失败、DNS污染或HTTP/2兼容性问题,需调http.timeout、禁用SSL验证或强制HTTP/1.1。

Composer install/update 卡在 “Resolving dependencies” 或 “Downloading” 阶段
这通常不是网络连通性问题,而是 Composer 在握手阶段(比如连接 packagist.org 或私有仓库)因 TLS 握手、DNS 解析、HTTP/2 兼容性或代理设置不当导致的隐性超时。默认超时值(process-timeout 和 http.timeout)对慢速网络或高延迟环境并不友好。
-
process-timeout控制的是整个命令执行的最长秒数(默认 300),但它不直接约束单次 HTTP 请求;真正影响握手的是http.timeout - 若使用 PHP 8.1+ + cURL 7.8x+,某些服务器启用了 HTTP/2 且服务端存在 TLS 扩展协商缺陷,会导致握手 hang 住——此时降级到 HTTP/1.1 更稳定
- 国内用户直连 packagist.org 经常触发中间设备干扰(如运营商 SNI 拦截),表现为无错误日志、无响应、CPU 占用低但进程不退出
修改 composer.json 中的 http 配置项
在项目根目录的 composer.json 里添加或覆盖 config 段,优先级高于全局配置:
{
"config": {
"http": {
"timeout": 600,
"ssl": {
"verify_peer": false,
"verify_peer_name": false
}
},
"process-timeout": 1200,
"fxp-asset": {"enabled": false},
"secure-http": false
}
}
-
http.timeout是关键:它控制每个 HTTP 请求(含 DNS 查询、TCP 连接、TLS 握手、首字节等待)的总耗时,默认为 0(即无限),但实际受底层 cURL 的CURLOPT_TIMEOUT影响;设为600可避免卡死 -
verify_peer和verify_peer_name设为false可绕过证书校验失败引发的握手阻塞(仅限调试或可信内网环境) -
secure-http设为false允许通过 HTTP 源安装(不推荐生产,但可验证是否为 HTTPS 层问题)
强制禁用 HTTP/2 并指定协议版本
如果确认是 HTTP/2 握手失败(常见于 macOS + Homebrew PHP + curl 7.85+),可在命令行中临时禁用:
COMPOSER_HTTP_VERSION=1.1 composer install
- 该环境变量会强制 Composer 使用 HTTP/1.1 发起所有请求,跳过 ALPN 协商环节
- 也可写入 shell 配置:
echo 'export COMPOSER_HTTP_VERSION=1.1' >> ~/.zshrc(注意不要长期启用,部分私有仓库可能依赖 HTTP/2 流控) - 验证是否生效:加
-v参数运行,查看日志中是否出现Using HTTP/1.1
检查并清理 Composer 缓存与 DNS 缓存
缓存损坏或本地 DNS 返回异常 IP(如被污染的 packagist.org A 记录)也会让握手卡在 connect 阶段:
- 清除 Composer 缓存:
composer clear-cache(注意不是dump-autoload) - 刷新系统 DNS:
sudo dscacheutil -flushcache(macOS)或ipconfig /flushdns(Windows) - 测试基础连通性:
curl -v https://packagist.org/packages/list.json—— 如果这里也卡住,说明问题在系统层而非 Composer - 临时换 DNS(如
8.8.8.8或1.1.1.1),排除本地解析器干扰
真正棘手的是那些没有报错、不打印重试信息、strace 显示卡在 connect() 或 recvfrom() 的情况——这时候得怀疑是不是公司防火墙做了 TLS 指纹识别拦截,或者 PHP 的 OpenSSL 版本太旧不支持服务端要求的密钥交换算法。


















