--timeout 不起作用是因为它是旧版别名,新版应使用 --http-timeout(对应配置项 http.timeout),且该参数仅控制单次 HTTP(S) 请求总耗时,不作用于 git clone 等子进程;同时必须配齐 http-proxy 和 https-proxy,后者协议头必须为 http://,否则 HTTPS 请求静默直连导致卡在 Loading composer repositories 或报 cURL error 28。

Composer 没有自动检测网络超时的能力,所谓“动态适配”必须靠外部脚本判断后传参;代理配置则必须同时设 http-proxy 和 https-proxy,且后者值协议头只能是 http://,否则 HTTPS 请求静默直连,卡在 Loading composer repositories。
为什么 --timeout 不起作用?该用哪个参数
很多人执行 composer update --timeout=600 却发现没效果——因为这个参数只对 update、install、require 的 HTTP(S) 请求阶段生效,且仅控制单次请求总耗时(DNS + TLS + 传输),不覆盖 git clone 或解压等后续步骤。更关键的是:--timeout 是旧版别名,新版 Composer 推荐用 --http-timeout,它对应配置项 http.timeout。
常见错误包括:
- 误以为
composer.json里写"timeout": 600或"process-timeout": 600能控制 HTTP 超时——其实process-timeout只管外部命令(如git),和网络无关 - 设了
--timeout=0或负数,触发curl_setopt(): CURLOPT_TIMEOUT value of 0 is not supported - PHP 层级的
default_socket_timeout(查法:php -i | grep default_socket_timeout)若低于你设的http.timeout,会提前掐断连接
代理必须配齐 http-proxy 和 https-proxy
Composer 对 HTTP 和 HTTPS 请求走两套完全独立的路由逻辑:所有包源(Packagist、GitHub API、镜像站)都走 HTTPS,只配 http-proxy 等于没配。漏掉 https-proxy,请求会 fallback 到直连,结果就是卡住无报错,或报 cURL error 28。
正确做法:
-
https-proxy的值协议头**必须是http://**,哪怕你的代理监听的是 HTTPS 端口(例如 Clash 默认http://127.0.0.1:7890) - 含特殊字符的密码要 URL 编码,比如
pa@ss/word→pa%40ss%2Fword,可用php -r "echo rawurlencode('pa@ss/word');"生成 - 验证是否生效:
composer config -g --list | grep -E "(http|https)-proxy",必须看到两行且格式合规 - NTLM 代理(如公司 Windows 域)需引入中转工具(
cntlm或px),让 Composer 连本地http://127.0.0.1:3128
怎么模拟“自动检测网络”再设 timeout
Composer 本身不测速也不自适应。可行方案是写个 shell wrapper,用 curl 测镜像源首包延迟,再决定传什么 --http-timeout:
curl -o /dev/null -s -w "%{time_total}\n" https://mirrors.aliyun.com/composer/packages.json -m 5
返回值 >2s 就传 --http-timeout=900,≤2s 用 600;测速失败(如超时或 DNS 解析失败)就 fallback 到保守值 1200。注意别用 ping——ICMP 不代表 HTTPS 可通,且多数 CDN 屏蔽 ping。
国内用户务必优先测镜像源(如阿里、腾讯),而不是 packagist.org;直连官方源在多数地区已不可行。
换源、调参、禁用并行,三者缺一不可
只调 timeout 或只配代理,大概率仍失败。真实场景下要组合操作:
- 全局换源:
composer config -g repos.packagist composer https://mirrors.aliyun.com/composer/ - 同步调高两个 timeout:
composer config -g http.timeout 600+composer config -g process-timeout 1800 - 禁用并行下载降低连接压力:
composer config -g use-include-path false,CI 中还可加COMPOSER_PROCESS_TIMEOUT=0 - CI/CD 必须显式设
COMPOSER_HOME和缓存~/.composer/cache,否则容器重启后配置丢失
最易被忽略的一点:换源后运行 composer config -g --list | grep repos.packagist 确认输出确实是镜像地址,而不是空或仍是 packagist.org——很多失败源于配置没真正写入全局。











