因为项目级 repositories 字段会无条件覆盖全局镜像配置,且依赖包自身的 repositories 声明被 composer 完全忽略;必须确保项目根目录 composer.json 中无 repositories 字段(或为空对象),并配合 clear-cache、删 vendor/ 和 composer.lock 后重装。

composer.json 里写 repositories 为什么不管用?
因为 Composer 只读取根项目(你执行 composer install 所在目录)的 composer.json,而依赖包自己声明的 repositories 字段会被完全忽略——这不是配置错误,是设计如此。你在某个依赖的 composer.json 里加了镜像源,Composer 压根不看。
更关键的是:如果你在自己的项目 composer.json 里手动写了 "repositories" 字段(比如 {"packagist.org": false} 或空数组),它会直接覆盖全局镜像配置,导致 repo.packagist 设置彻底失效。
- 常见错误现象:
composer config -g repo.packagist显示正确,但composer install日志里仍出现packagist.org - 检查方法:打开项目根目录下的
composer.json,搜索"repositories"字段是否存在 - 临时验证:运行
composer config --unset repositories清掉项目级干扰项,再试
~/.composer/config.json 是怎么被读取的?
全局镜像配置实际写入的是用户家目录下的 ~/.composer/config.json(Windows 是 %APPDATA%\Composer\config.json),Composer 启动时自动加载,优先级高于默认值,但低于项目级 composer.json 中的 repositories。
这个文件只对“调用它的 PHP 解释器”生效。比如群晖 NAS 上 WebStation 用的是 /volume1/@appstore/PHP82/usr/bin/php,那你必须用这个路径执行 composer config -g,否则配置写进去了也白搭。
- 验证是否真写进去了:
composer config -g repo.packagist输出必须是完整 JSON,如{"type": "composer", "url": "https://mirrors.aliyun.com/composer/"} - 如果输出为空或报错,说明没写成功;可能原因包括:拼错键名(
repos.packagist多了个 s)、权限不足、用了 sudo 导致写进 root 用户配置 - Windows 下 CMD 对引号敏感,命令中不要加引号,直接粘贴执行
项目级配置怎么安全写入 composer.json?
项目级配置不是手改 composer.json,而是用 composer config 命令追加,避免 JSON 格式错误或破坏已有结构。
它会把镜像声明安全地塞进 repositories 字段下,前提是该字段当前是对象({}),不是数组([])。如果是数组,命令会直接报错,得先手动改成空对象。
- 命令是:
composer config repo.packagist composer https://mirrors.aliyun.com/composer/(注意没有-g) - 它只添加
"packagist"子项,不会覆盖已有的私有源(比如 type=package 的条目) - 切忌手写
"packagist.org": false—— 这会关掉所有回退机制,镜像挂了就直接失败 - CI/CD、Docker、宝塔等多用户环境,项目级配置比全局更可靠,因为它可提交 Git,所有环境行为一致
换源后还是卡在 Loading composer repositories 怎么办?
这不是配置无效,而是 Composer 在读缓存或旧锁文件里的元数据地址。即使你刚配好镜像,它也可能还在用 composer.lock 里记录的旧 URL 发请求。
必须清掉本地缓存和旧状态,否则日志里永远看不到镜像域名。
- 第一步:
composer clear-cache - 第二步:删掉项目下的
vendor/和composer.lock - 第三步:用
composer install -vvv观察日志,确认请求发往mirrors.aliyun.com或你设的镜像域名 - 如果还卡住,加
--no-cache参数强制跳过缓存:composer update --no-cache
键名、type 值、URL 结尾斜杠这三样缺一不可,少一个都会静默回退到官方源——这种失败不报错,只悄悄变慢。











