直接调高process-timeout和http.timeout才能真正解决cURL error 28问题:http.timeout控制HTTPS请求全过程(DNS+TLS+首字节+body)总时长,默认300秒;process-timeout控制git clone等子进程超时,默认300秒;二者必须同步调高,并匹配PHP的default_socket_timeout。

直接调高 process-timeout 和 http.timeout 才能真正解决大文件下载卡在 Downloading https://... 或报 cURL error 28 的问题——只换镜像或只改 PHP 配置没用。
卡在 Downloading https:// 时该调 http.timeout
这是 HTTP 请求阶段超时,比如拉 ZIP 包、读取 packages.json,错误里常带 cURL error 28 或反复 retry。它和 process-timeout 完全无关,只认 http.timeout(Composer 2.x)。
- 单位是秒,默认仅 300(5 分钟),弱网或大包下极易触发
- 项目级最稳:运行
composer config http.timeout 600,写入当前composer.json的config段,可提交、可复现 - 全局生效:用
composer config -g http.timeout 600,写入~/.composer/config.json - 临时覆盖优先级最高:设环境变量
COMPOSER_HTTP_TIMEOUT=1200 composer install -
php -i | grep default_socket_timeout查出的值若低于你设的http.timeout(常见为 60),会提前掐断连接,必须同步调高
The process timed out 错误该调 process-timeout
错误里一定含 [RuntimeException] The process "" exceeded the timeout,加 -vvv 可看到最后那条命令。这是子进程(如 git clone、unzip、post-install-cmd)执行太久被杀,和网络请求无关。
- 默认 300 秒,影响所有外部命令生命周期,不可通过
composer.json覆盖 - 全局改:运行
composer config -g process-timeout 1800(30 分钟) - 项目级改:直接在
composer.json顶层加"config": {"process-timeout": 1200} - 临时覆盖:
COMPOSER_PROCESS_TIMEOUT=1800 composer install或--process-timeout=1800 - 设为 0 表示禁用超时,但可能卡死无响应;调试建议先设 600,确认能走通再调高
代理环境下必须同时配 http-proxy 和 https-proxy
只配 http-proxy 一定失败。Composer 对 HTTP/HTTPS 请求走两套独立路由,所有包仓库(包括阿里云镜像)都走 HTTPS,未配 https-proxy 会导致静默直连,表现为卡在 Loading composer repositories 或反复报 cURL error 28。
-
https-proxy的协议头必须是http://,哪怕代理监听 HTTPS 端口,例如:http://127.0.0.1:7890 - 密码含
@或/必须 URL 编码,如pa%40ss%2Fword - 验证是否生效:
composer config -g --list | grep -E "(http|https)-proxy",必须看到两行且格式合规 - 代理配好后仍卡住?检查镜像地址末尾是否多了一个
/(如https://mirrors.aliyun.com/composer//),导致拼接 URL 失败
别踩这些坑:无效操作和隐藏依赖
很多尝试看似合理,实际完全无效,容易浪费排查时间。
-
set_time_limit(0)或改php.ini的max_execution_time对 Composer 下载逻辑无效——它自己封装 cURL,不走 PHP 超时机制 -
composer.json里写"timeout": 600在config下是错的,正确字段名是http.timeout和process-timeout -
http-basic-timeout是旧参数(Composer 2.2+ 已弃用),现在统一由http.timeout控制 - 单纯加 timeout 只解决“等太久”,不解决“连不上”;若镜像不支持
Range请求,大文件无法断点续传,加再久也会失败
最关键的不是数值设多大,而是两个 timeout 必须成对调整,且要和代理、镜像、PHP socket 设置对齐——漏掉任意一环,都可能让 30 分钟的等待最终变成一次无声的失败。


















