composer 无法内置限速,需通过支持限速的 http/https 代理(如 mitmproxy、charles proxy 或 throttle-proxy)拦截其下载请求;注意 composer 默认不读取系统 http_proxy 环境变量对 https 的支持,需显式配置。

用 composer install 时怎么让网络变慢?
直接改 Composer 本身不行——它没内置限速开关。得靠外部代理把请求“卡住”。核心思路是:让 Composer 的所有包下载请求(packagist.org 或私仓)经过一个能限速的 HTTP 代理,而不是直连。
常见错误是试图用 curl --limit-rate 或系统级流量控制(如 tc),但 Composer 底层用的是 PHP 的 stream_context 或 cURL 扩展,不走 shell 层面的 curl 命令,所以无效。
- 必须用支持 HTTP/HTTPS 代理且可配置带宽的工具,比如
mitmproxy、Charles Proxy或轻量级的throttle-proxy - Composer 默认不读系统
http_proxy环境变量对 HTTPS 请求的支持(尤其 PHP - 私有仓库若用自签名证书,代理会触发 ssl 验证失败,得配合
composer config -g disable-tls false和证书信任
推荐方案:throttle-proxy 快速起手
它是个极简 Node.js 工具,专注限速,没 ui、不存日志、启动快,适合本地开发临时压测。比 mitmproxy 少一堆证书配置,比 Charles 少 license 和 GUI 依赖。
安装和运行:
npm install -g throttle-proxy throttle-proxy --port 8080 --rate 50k
这会在本地开一个 http://localhost:8080 代理,所有经它转发的响应被硬限在 50 KB/s。
- 启动后,用
export http_proxy=http://localhost:8080(linux/macos)或set http_proxy=http://localhost:8080(windows CMD) - 必须同时设
https_proxy,否则 HTTPS 包源(如packagist.org)直连,绕过限速 - PHP CLI 进程默认读环境变量,但某些 ide(如 phpstorm)的终端可能不继承,建议在终端里手动 export 后再跑
composer install
composer config 里 proxy 设置为什么经常失效?
因为 composer config -g http-proxy ... 只影响 Composer 自己的 HTTP 客户端(比如访问 packagist.org 元数据),但实际下载 zip/tar 包时,它会调用系统 cURL 或 PHP stream,走的是操作系统级代理环境变量,不是 Composer 配置项。
-
composer config -g http-proxy对元数据请求有效,但对包文件下载无效——这是最常踩的坑 - 验证是否生效:运行
composer install -vvv,看日志里下载.zip文件时用的是file_get_contents还是cURL,再检查对应方式是否读取了http_proxy - PHP 8.0+ 在使用 cURL 时,若未设
CURLOPT_PROXY,即使有环境变量也不一定转发;稳妥做法是确保http_proxy+https_proxy都设,且 PHP 编译时启用了 cURL
慢速下 composer install 容易触发哪些真实失败?
不是单纯“变慢”,而是暴露出平时忽略的超时和重试逻辑缺陷。典型表现:
-
Connection timeout或cURL Error 28: Operation timed out:Composer 默认连接超时是 300 秒,但下载超时只有 60 秒(process-timeout默认值),大包在 50 KB/s 下很容易超 - 部分包下载中断后不自动重试,卡在
Downloading ...不报错,实际是 Composer 旧版本( - 并发下载(
composer install -j4)在限速代理下会挤占带宽,导致多个请求一起超时,看起来像随机失败 - 解决办法:加大下载超时
composer config -g process-timeout 600,关并发-j1,或换更稳定的代理(throttle-proxy比某些 mitm 实现更少丢包)
真正难测的不是“能不能装完”,而是断网重连、包校验失败、临时 503 后续恢复这些边界——限速只是把它们从概率事件变成必现问题。代理一关,问题就藏回去,所以测试时别只跑一次。