不能只设一个 timeout,必须区分 http.timeout(管 HTTPS 下载)、process-timeout(管 unzip/git clone 等子进程)、http-basic-timeout(管单次 HTTP GET 连接/读取),三者独立、缺一不可。

直接结论:不能只设一个 timeout,必须区分 http.timeout(管 HTTPS 下载)、process-timeout(管 unzip/git clone 等子进程)、http-basic-timeout(管单次 HTTP GET 连接/读取),三者独立、缺一不可。
卡在 Downloading https:// 时该调哪个参数
这是 HTTP 传输阶段卡住,典型错误是 cURL error 28 或反复 retry 后失败。它完全不看 process-timeout,只响应 http.timeout 和 http-basic-timeout:
-
http.timeout控制整个 HTTPS 请求生命周期(DNS + TLS + 首字节等待 + 全量 body 传输),默认仅 300 秒,弱网下拉一个 200MB 的 dist ZIP 很容易超时;建议设为1200 -
http-basic-timeout(Composer 2.2+)更细粒度,只管单次 GET 的连接与初始读取(比如拉packages.json或 ZIP 头部),默认 60 秒太激进;建议设为300 - PHP 底层的
default_socket_timeout必须 ≥http.timeout,否则 cURL 会在底层提前中断——用php -i | grep default_socket_timeout查,若为 60,需同步改 PHP 配置
报 The process "" exceeded the timeout 该调哪一项
错误里明确含 The process 字样,说明是子进程执行太久被杀,比如 unzip、git clone、tar -xzf 或 post-install-cmd 脚本。这和 HTTP 完全无关,只由 process-timeout 控制:
- 默认 300 秒,解压含大量文件的 Laravel 或 Symfony dist 包常超时
- 项目级生效:
composer config process-timeout 1800(写入当前composer.json的config段) - 全局生效:
composer config -g process-timeout 1800(写入~/.composer/config.json) - 临时覆盖优先级最高:
COMPOSER_PROCESS_TIMEOUT=2000 composer install,CI 中推荐这种写法
--timeout= 参数到底怎么用
这是最常用、最轻量的临时干预方式,但细节极易出错:
- 必须带等号:
--timeout=1200,写成--timeout 1200会被静默忽略 - 它只覆盖
process-timeout,对http.timeout和http-basic-timeout无效 - Composer 2.2+ 才支持配套的
--http-basic-timeout=300,旧版本只能靠换源或调全局配置硬扛 - 它无法解决根本瓶颈:网络丢包、镜像响应慢、磁盘 I/O 卡顿——只是“多等一会儿”,不是“修复问题”
为什么改了 composer.json 里的 config.timeout 没用
因为 config.timeout 是个早已废弃的无效字段,Composer 根本不识别它。你看到的旧文档或教程写的这个 key,从 Composer 1.x 后期起就不再起效:
- 真正起效的是三个独立参数:
http.timeout、process-timeout、http-basic-timeout -
http.timeout不能通过composer.json的config段设置(会报 warning 并忽略),只能靠环境变量或全局 config -
process-timeout和http-basic-timeout可以写进composer.json,但必须放在顶层config对象内,格式为:"config": {"process-timeout": 1800, "http-basic-timeout": 300}
最容易被忽略的一点:哪怕你把所有 timeout 都设到 3600,只要 PHP CLI 的 default_socket_timeout 还是默认 60,cURL 就会在第 60 秒直接断连——这个底层限制不在 Composer 控制范围内,必须手动检查并同步调整。


















