应同时调高process-timeout(控制git clone等外部命令)和http-basic-timeout(控制HTTP请求首字节读取),默认值分别为300秒和60秒,需全局、项目级或临时参数协同配置,并确保PHP的default_socket_timeout不低于http-basic-timeout。

Composer拉取超时不是网络连不上,而是它自己设的“等多久就放弃”太短——默认 300 秒(5 分钟),遇到大 ZIP 包、弱网或国内镜像响应慢,curl error 28 或 failed to open stream: Connection timed out 就直接报错中断。只改 PHP 的 max_execution_time 没用,Composer 不走那套逻辑。
该调哪几个 timeout 参数?
Composer 有两层独立超时,必须同时看:
-
process-timeout:控制单个外部命令(如git clone、unzip、curl下载完整 ZIP)最长执行时间,默认 300 秒 -
http-basic-timeout:Composer 2.2+ 新增,专管单次 HTTP 请求的连接 + 首字节读取(比如拉packages.json或 ZIP 包头几 KB),默认仅 60 秒
常见错误现象:Downloading https://... 卡住 → 多半是 http-basic-timeout 先触发;The process "unzip ..." exceeded the timeout → 是 process-timeout 生效。两者缺一不可。
怎么改才真正生效?
别碰 composer.json 里的 config.timeout 字段——它早被废弃,写了也无效。正确方式分三类:
- 全局永久生效(推荐):
composer config -g process-timeout 1800<br>composer config -g http-basic-timeout 300
- 当前项目生效(去掉
-g):composer config process-timeout 1200<br>composer config http-basic-timeout 240
- 临时覆盖(CI/调试首选):
composer install --timeout=1800 --http-basic-timeout=300
注意:--http-basic-timeout 在 Composer 2.2+ 才支持;旧版本只能靠 --timeout 硬扛,但效果差(它会把整个流程都拖长,不精准)。
为什么改了还是卡?容易踩的坑
常见失效原因不是命令写错,而是底层被掐断或配置冲突:
- PHP CLI 的
default_socket_timeout必须 ≥ 你设的http-basic-timeout,否则 socket 层在 60 秒就强制断开(查法:php -i | grep default_socket_timeout) - 环境变量
COMPOSER_PROCESS_TIMEOUT优先级高于 config 文件,若已设为 300,再改 config 也不生效 - 用了国内镜像但没关 packagist.org 回源,Composer 仍会偷偷去境外源 fallback,一卡就超时
- 某些 CI 环境(如 GitHub Actions)默认挂载只读文件系统,
composer.json或composer.lock权限不足,导致下载完解压失败,误判为超时
比调 timeout 更有效的做法
单纯加 timeout 是“等得更久”,不是“下得更快”。真正稳定的做法是组合使用:
- 换国内镜像源:
composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/ - 禁用 packagist.org 回源(避免 fallback):
composer config -g repos.packagist false - 关并行下载(降低连接压力):
composer config -g parallel-downloads 1 - 确认 DNS 解析正常(比如设为
8.8.8.8或223.5.5.5)
这些操作对弱网和 CI 构建的影响,远大于把 process-timeout 改成 3600 —— 超时只是表象,连接质量才是根因。


















