必须在 repositories 首位显式禁用 packagist.org,即 {"packagist.org": false},再配置镜像源;URL 末尾不能带 /,需 HTTPS;改后必须 composer clear-cache;私有包需 type: "package" 声明或确保镜像已同步;dev 版本需用 @dev 或 inline alias 控制稳定性;验证是否真走镜像源须看 composer update -vvv 日志中所有 p2/ 请求域名。

composer.json 的 repositories 字段必须显式禁用 packagist.org
不加这一步,哪怕写了国内镜像地址,Composer 仍会 fallback 到官方源查包,导致 Could not find package xxx 或版本解析失败。这不是“没生效”,而是两个源同时参与请求,优先级混乱。
正确写法是把 {"packagist.org": false} 放在 repositories 数组首位,再跟镜像仓库:
{
"repositories": [
{ "packagist.org": false },
{
"type": "composer",
"url": "https://mirrors.aliyun.com/composer/"
}
],
"require": { ... }
}
-
url末尾不能带/,否则 404(如https://mirrors.aliyun.com/composer/❌) - 镜像地址必须是完整 HTTPS URL,HTTP 需额外加
"secure-http": false - 改完后必须运行
composer clear-cache,composer update --no-cache不够用
想让某个包走私有源或特定镜像,不能只靠 --repository-url
composer require vendor/package --repository-url https://xxx 只替换元数据获取地址,但 Composer 仍按原始包名去原源匹配版本。如果私有源里没有这个包,或者版本未同步,就会直接报错或 fallback。
真正生效的方式只有两种:
- 在
repositories中声明一个type: "package"仓库,手动列出该包的name、version和dist字段(适合私有包、dev 分支等不可见于公共索引的场景) - 在
repositories中声明type: "composer"镜像,并确保该镜像已同步目标包(比如阿里云镜像已包含topthink/framework) - require 中必须显式写全包名,且与
repositories中声明的name完全一致(大小写、vendor 名都不能错)
处理依赖链里的 dev 版本要小心稳定性设置
如果 A 包依赖 "vendor/b": "dev-main",而你的项目没允许 dev 稳定性,composer install 会卡住或报错,不是网络问题,是 Composer 主动拒绝加载。
推荐做法不是全局设 minimum-stability: dev,而是精准控制:
- 对单个包用
@dev后缀:"vendor/b": "dev-main@dev" - 用 inline alias 映射版本:
"vendor/b": "dev-main as 2.1.0",让依赖解析能对上其他包的约束 - 避免在
require-dev里混写生产依赖,dev 分支包容易污染 lock 文件稳定性
验证是否真走配置的镜像源,别信下载速度
缓存没清干净、镜像未同步、URL 写错,都可能导致表面“装得快”,实际仍从 packagist.org 拉了部分元数据。
最可靠验证方式是:
- 执行
composer update -vvv - 搜索日志中类似
GET https://mirrors.aliyun.com/composer/p2/vendor/package.json的行 - 确认所有
p2/xxx.json请求都指向你配置的镜像域名,而不是packagist.org
漏掉任何一条 GET 请求走错源,都可能造成后续版本解析偏差——这点最容易被忽略。


















