← 返回博客列表

Composer 与 Packagist 安装依赖失败:curl error 28 超时、GitHub 限流、镜像切换与内存不足全解

2026-10-13 · 刺猬VPN

写 PHP 项目绕不开 Composer:新建 Laravel 项目要执行 composer create-project,接手老项目第一件事是 composer install。可在国内执行时,终端常常卡在「Loading composer repositories with package information」很久不动,接着报「curl error 28 while downloading https://repo.packagist.org/p2/...: Operation timed out」;或者元数据下载完了,开始安装时一行行刷出「Failed to download xxx from dist」,然后「Now trying to download from source」,开始用 git 克隆,慢得令人绝望;还有人看到「GitHub API limit exhausted」,被要求创建一个令牌。

这些报错对应的是不同阶段。Composer 先从 repo.packagist.org 下载包的元数据,解析出要装哪些版本;然后按 composer.lock 或解析结果下载每个包的压缩包,压缩包大多托管在 GitHub 的代码下载服务上;压缩包下载失败时,它会退回到用 git 克隆源码。所以元数据超时要处理 Packagist 的连接,压缩包失败要处理 GitHub 的连接与限流,两段分开处理效率最高。另有一类报错与网络无关,例如依赖冲突与内存不足,也会在下文单独列出。

Composer 两段下载分别走哪里

看报错时先找地址:出现 packagist 就是元数据阶段,出现 github 或 codeload 就是压缩包阶段,出现 could not be resolved 就是版本冲突。国内镜像能同时缓存元数据与压缩包,但不覆盖私有包,也可能比官方晚几分钟到几小时。

阶段默认地址典型报错处理方向
包元数据repo.packagist.orgcurl error 28 或 packages.json 无法下载线路或镜像
代码压缩包GitHub 代码下载服务Failed to download from dist线路与 GitHub 令牌
回退源码克隆github.com 的 git 仓库git clone 超时或很慢安装 zip 扩展避免回退
GitHub 接口api.github.comAPI limit exhausted配置 GitHub 令牌
私有包私有仓库或 Satis401 或 403auth.json 凭据
依赖解析本地计算could not be resolved to an installable set改版本约束,与网络无关

从卡住到装好依赖:分步操作

  • 第一步:先把网络线路准备好。安装刺猬VPN,自定义用户名和密码注册,不需要邮箱和手机号,连上后先用浏览器打开 repo.packagist.org/packages.json 与 github.com,两个都能打开再回到终端。免费节点永久免费、不限流量、不限速,适合先判断是不是网络问题;
  • 第二步:让终端用上线路。Composer 读取 HTTP_PROXY、HTTPS_PROXY 与 NO_PROXY 环境变量,Windows PowerShell 用 $env:HTTPS_PROXY 设置,macOS 与 Linux 写进 shell 配置文件;执行 composer diagnose,看「Checking https connectivity to packagist」一项是否为 OK;
  • 第三步:确认没有残留的镜像配置。执行 composer config -g repos.packagist 查看全局仓库设置,如果指向一个已经停止服务的镜像,用 composer config -g --unset repos.packagist 删掉,恢复官方源;
  • 第四步:配置 GitHub 令牌。在 GitHub 的「Settings」「Developer settings」「Personal access tokens」里生成一个只读令牌,执行 composer config -g github-oauth.github.com 你的令牌,从此 GitHub 接口限额会大幅提高;
  • 第五步:检查 PHP 扩展。执行 php -m 看是否有 zip 与 openssl,缺少 zip 扩展又没有 unzip 命令时,Composer 会提示「The zip extension and unzip/7z commands are both missing」并回退到 git 克隆,安装扩展后速度会快很多;
  • 第六步:清缓存后重试。执行 composer clear-cache,再执行 composer install -vvv,详细输出会显示每个请求的地址与耗时,卡在哪里一目了然;
  • 第七步:大型项目内存不足时,报「Allowed memory size of ... bytes exhausted」,临时设置环境变量 COMPOSER_MEMORY_LIMIT=-1 再执行,或者升级到 Composer 2,它的内存占用小得多;
  • 第八步:安装完成后,把 composer.lock 提交进仓库,团队其他成员与部署环境执行 composer install 时会按锁文件下载同一组版本,不必重新解析。

按报错的那一行排查

  • curl error 28 Operation timed out:到 Packagist 的连接超时,确认代理变量在当前终端生效,或临时切换镜像;
  • packages.json file could not be downloaded:元数据入口打不开,用浏览器访问同一地址对比,浏览器能开就是终端代理没生效;
  • Failed to download from dist 后转为 source:压缩包下载失败,检查到 GitHub 的连接与 zip 扩展;
  • GitHub API limit exhausted:未登录的接口限额用完,配置 GitHub 令牌;
  • SSL certificate problem: unable to get local issuer certificate:PHP 找不到根证书,在 php.ini 里设置 openssl.cafile 指向有效的证书包,或关闭杀毒软件的 HTTPS 扫描;
  • Your requirements could not be resolved to an installable set of packages:版本冲突,阅读报错里的依赖链,调整 composer.json 的版本约束或 PHP 版本;
  • The process exceeded the timeout of 300 seconds:某个进程执行太久,设置 COMPOSER_PROCESS_TIMEOUT 为更大的值。

官方源、国内镜像与线路怎么选

镜像的优势是不需要代理,缺点是可能滞后、偶尔停服,而且你刚发布的新版本要等镜像同步才能装。团队里有人维护自己的开源包,或者依赖刚发布的修复版本,直连官方更省心。刺猬VPN支持按域名的智能分流,可以只让 packagist.org 与 github.com 相关域名走线路,国内服务照常直连。实际可用性取决于当前网络环境。

对比项会员节点直连官方国内镜像免费节点
包的新鲜度与 Packagist 实时一致可能延迟几分钟到几小时与官方一致
压缩包下载直接从 GitHub 下载镜像缓存,速度较快直接从 GitHub 下载
私有包支持不覆盖支持
配置成本设一次代理变量一条 composer config 命令同左
流量时长套餐有效期内不限流量、不限速由镜像决定永久免费、不限流量、不限速
适合场景日常开发与发布新版本只装常用包且能接受延迟先判断是不是网络问题

Windows、macOS 与 Docker 环境的差异

Windows 上最常见的问题是 PHP 的 openssl 与 curl 扩展没启用,或者 php.ini 有多份,命令行用的不是你改过的那份。执行 php --ini 看命令行实际加载的配置文件路径,在那份文件里启用扩展。环境变量设在 PowerShell 窗口里只对当前窗口有效,长期使用要在系统的环境变量设置里添加。

macOS 用 Homebrew 安装的 PHP 与系统自带的 PHP 可能同时存在,执行 which php 确认用的是哪一个。Docker 容器里执行 composer install 时,容器默认不继承宿主机的代理设置,要在 docker run 时用 -e 传入代理变量,或者在 Dockerfile 里用构建参数传入,构建完成后别把代理写死进镜像。持续集成里缓存 Composer 的缓存目录,可以避免每次构建都重新下载。

锁文件、团队协作与部署

composer.lock 记录了每个依赖的确切版本与下载地址,应用项目应当提交它。团队成员执行 composer install 时按锁文件下载,结果完全一致;只有在需要升级依赖时才执行 composer update,并把更新后的锁文件提交。如果有人在镜像环境下执行了 update,锁文件里的下载地址可能变成镜像地址,其他人直连官方时仍然能用,因为 Composer 会按仓库设置重新定位,但最好在团队里统一一种来源,避免混乱。

部署到生产服务器时,执行 composer install --no-dev --optimize-autoloader,只装生产依赖并优化自动加载。服务器在境外时一般不存在网络问题;服务器在国内时,要么配置镜像,要么在构建机上装好依赖再连同 vendor 目录一起部署,不要让生产服务器在发布时临时去拉依赖。

Composer 1 与 Composer 2 的差别

还在用 Composer 1 的老项目,网络问题会被放大很多。Composer 1 的元数据格式要一次下载大量文件,单线程逐个下载压缩包,内存占用也高;Composer 2 改用了更精简的元数据格式,并行下载压缩包,速度与稳定性都明显更好。执行 composer --version 确认版本,如果还是 1.x,执行 composer self-update --2 升级。

升级前确认项目里的插件兼容 Composer 2,少数老插件只支持 1.x,升级后会报插件 API 版本不匹配。遇到这种情况先升级插件本身;实在不能升级,可以用 composer self-update --1 临时退回。官方对 Composer 1 的元数据支持已经大幅缩减,长期来看迟早要迁移。

新建项目时的特殊情况

执行 composer create-project 新建 Laravel、Symfony 等框架项目时,Composer 先下载框架骨架,再安装骨架里声明的全部依赖,一次要下载上百个包,是最容易超时的场景。如果中途失败,生成的目录里只有一半文件,不要在这个半成品上继续执行 install,直接删掉整个目录重新创建,否则锁文件与 vendor 目录可能对不上。

很多框架安装器本质上也是调用 Composer,例如 Laravel 的安装器,它同样读取 Composer 的代理与镜像设置。创建项目后框架往往还会自动执行一些脚本,例如生成密钥、发布配置,这些脚本失败时报的是 PHP 错误而不是下载错误,要按报错信息单独处理。

私有包与凭据配置

公司内部的私有包通常放在私有 Git 仓库、Satis 或 Private Packagist 上,需要在 composer.json 的 repositories 里声明地址,并提供凭据。凭据不要写进 composer.json,而是写进项目根目录或用户目录下的 auth.json,并把项目里的 auth.json 加入 .gitignore,避免令牌被提交进仓库。

私有仓库报 401 或 403 时,先确认令牌没有过期、权限包含读取该仓库;报超时时,先确认私有仓库本身的地址能访问。私有包的地址不在国内镜像的覆盖范围内,切换镜像对它没有任何作用,这一点常被忽略。如果私有仓库在公司内网,记得把它的域名写进 NO_PROXY,否则请求会被送到外部线路上,反而连不上。

迁移到新电脑时的顺序

  • 先安装 PHP 并启用 openssl、curl、zip、mbstring 等常用扩展,执行 php -m 确认;
  • 安装 Composer 2,执行 composer --version 看到版本号再继续;
  • 设置代理变量或镜像,执行 composer diagnose,所有检查项为 OK;
  • 配置 GitHub 令牌与私有仓库的 auth.json;
  • 最后进入项目执行 composer install,不要把旧电脑的 vendor 目录直接拷过来,PHP 版本不同时扩展编译结果可能不兼容。

和其他开发下载工具的分工

PHP 项目的前端部分往往还要用 npm,有时还要拉 Docker 镜像,这些工具各有自己的镜像与代理配置,不要用 Composer 的设置去修它们,统一的排查思路见 npm、pip、Docker 拉取失败排查。

Composer 的压缩包与源码克隆都依赖 GitHub,克隆慢、下载慢、Git 推送超时的处理方法见 GitHub 访问与下载加速。先让 GitHub 稳定可用,Composer 的大部分问题就随之消失。

常见报错速查表

现象原因解决办法
curl error 28到 Packagist 超时确认代理变量生效或切换镜像
Failed to download from distGitHub 压缩包下载失败检查 GitHub 连接与 zip 扩展
API limit exhaustedGitHub 接口限额用完配置 GitHub 令牌
SSL certificate problemPHP 找不到根证书设置 openssl.cafile
could not be resolved版本约束冲突调整 composer.json
Allowed memory size exhausted内存不足COMPOSER_MEMORY_LIMIT=-1
exceeded the timeout进程超时加大 COMPOSER_PROCESS_TIMEOUT

高频问答

  • 问:设置了系统代理为什么 Composer 还是超时?答:Composer 读的是 HTTPS_PROXY 等环境变量,在终端里显式设置一次;
  • 问:镜像和官方源能混用吗?答:可以,但同一项目最好统一,避免锁文件里的地址混乱;
  • 问:GitHub 令牌需要什么权限?答:只读公共仓库即可,不要给多余的写权限;
  • 问:composer update 和 install 有什么区别?答:install 按锁文件安装,update 会重新解析并改写锁文件;
  • 问:为什么装得特别慢?答:多半是缺少 zip 扩展导致回退到 git 克隆,或者 GitHub 连接不稳;
  • 问:免费节点够用吗?答:够判断网络问题,首次安装大型项目建议用时长套餐,有效期内不限流量、不限速。

把 Composer 环境一次配稳

Composer 与 Packagist 安装失败,拆开看是元数据、压缩包、GitHub 接口三段各自的问题,外加与网络无关的版本冲突和内存不足。先让浏览器能打开对应地址,再让终端代理生效、配好 GitHub 令牌、装上 zip 扩展,用 composer diagnose 与 -vvv 输出逐段验证,问题就能快速定位。

刺猬VPN采用 HTTPS+AES 加密传输,自定义用户名和密码即可匿名注册,不需要邮箱和手机号;免费节点永久免费、不限流量、不限速;时长套餐有效期内不限流量、不限速,客户端支持按域名与 IP 的智能分流和断线保护,一个账号可在多台开发机上使用。依赖能否顺利下载取决于当前网络环境。

开发者的稳定通道:用刺猬VPN流畅访问 GitHub 与全球开发资源

刺猬VPN提供永久免费节点,不限流量;无需邮箱,自定义用户名即可匿名注册。一个账号支持多设备同时在线,实际可用性取决于当前网络环境。