卡在Downloading https://xxx.zip时应调http-basic-timeout(Composer 2.2+)或http.timeout(旧版),二者均控制HTTP请求阶段超时,默认值过低易触发cURL error 28,需同步调高PHP的default_socket_timeout。

下载 ZIP 包失败,90% 不是网络断了,而是 Composer 在两个不同阶段分别超时了 —— 你只调一个参数,大概率白改。
卡在 Downloading https://xxx.zip 时该调哪个 timeout
看 composer install -vvv 最后一行:如果停在 Downloading https://,说明是 HTTP 请求阶段卡住,不是解压慢,而是连不上或首字节太慢。这时必须调 http-basic-timeout(Composer 2.2+)或旧版的 http.timeout。
-
http-basic-timeout控制单次 GET 的连接 + 读取(比如拉 ZIP 头几 KB),默认仅 60 秒,国内 DNS/TLS 握手抖动常见,设为300更稳 -
http.timeout是旧版总控参数(DNS + TLS + 首字节 + 整个 body),默认 300 秒,弱网下拉几百 MB ZIP 很容易超,建议设1200 - 注意:
config.timeout是无效字段,写进composer.json的config段完全不生效
卡在 Extracting xxx.zip 或 The process timed out 时该调谁
错误里出现 The process "unzip -qq" 或 exceeded the timeout,说明已成功下载 ZIP,但解压/克隆/运行脚本卡住了 —— 这和 HTTP 完全无关,http-basic-timeout 再大也没用。
- 必须调
process-timeout,它管unzip、git clone、tar -xzf这类子进程,默认 300 秒,解压大 dist 包常需1800 - 这个参数不能写进项目级
composer.json的config段(Composer 会忽略),只能全局设:composer config -g process-timeout 1800 - 临时覆盖优先级最高:
COMPOSER_PROCESS_TIMEOUT=2000 composer install
PHP 底层 socket 超时会提前掐断,哪怕你设了 1200
Composer 的 http.timeout 再大,如果 PHP CLI 的 default_socket_timeout 是默认的 60 秒,cURL 在底层就会被强制中断,错误里常带 cURL error 28。
- 查当前值:
php -i | grep default_socket_timeout - 临时绕过:
php -d default_socket_timeout=1200 composer install - 永久改法:编辑
php.ini中的default_socket_timeout = 1200(注意是 CLI 的 php.ini,不是 web 的)
换镜像源比加 timeout 更治本,但要注意绕过陷阱
阿里云镜像能缓解 DNS 污染、TLS 握手延迟、源响应慢,但不是万能的:
- 设镜像:
composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/ - 必须清缓存:
composer clear-cache,否则仍可能从损坏的本地缓存读 ZIP - Git 类包(
"type": "git")会绕过镜像直连 GitHub,此时process-timeout和 Git 自身超时才关键 - 中断后别直接删
vendor/—— 精准清理:rm vendor/autoload.php && rm -rf vendor/composer/,再composer dump-autoload && composer install
真正麻烦的从来不是“设多大 timeout”,而是中断后残留的破损 ZIP 文件 —— 它们校验失败却不报错,下次还试图用,直到 Content-Length mismatch 才暴露。这种状态不会自动恢复,必须手动清缓存或删临时目录。


















