根本原因是composer.json中repositories数组顺序决定依赖来源优先级,阿里云等镜像仅代理packagist.org官方索引,不覆盖vcs或自定义仓库;私有包需置顶声明且类型正确。

composer install 时为什么总是装错版本?
根本原因不是包没更新,而是 composer.json 里没显式锁定依赖来源优先级。Composer 默认按 repositories 数组顺序查包,靠前的镜像或仓库有更高优先级——但很多人以为设了阿里云镜像就“全局生效”,其实只是改了 packagist.org 的代理,对私有包、vcs 包或自定义仓库完全无效。
- 镜像(如
https://mirrors.aliyun.com/composer/)只代理 packagist.org 官方索引,不覆盖你手动加的vcs或package类型仓库 -
repositories数组里越靠前的仓库,匹配到同名包时越优先被选用,哪怕它版本更旧 - 如果两个仓库都提供
monolog/monolog,而你把私有 fork 放在数组末尾,Composer 就会跳过它,直接从 packagist 镜像装官方版
怎么让私有包强制优先于 packagist?
把私有仓库声明放在 repositories 数组最前面,并确保类型正确。尤其注意:type 为 vcs 的仓库,必须用 Git URL;type 为 package 的,要手动写完整包信息,否则 Composer 不认。
- 正确示例(Git 私仓优先):
"repositories": [ { "type": "vcs", "url": "https://git.example.com/my/monolog" }, { "type": "composer", "url": "https://mirrors.aliyun.com/composer/" } ] - 错误写法:
"url": "https://git.example.com/my/monolog.git"(带 .git 后缀在某些 Composer 版本会失败) - 如果你用的是
package类型,必须包含version和dist字段,否则composer install会跳过该包
composer config repo.packagist false 是干啥的?
这是关闭默认 packagist.org 索引的开关,常用于纯内网环境。但它不会自动提升你镜像的优先级,反而可能让所有非显式声明的包直接报 Package not found 错误。
- 启用后,所有依赖都必须出现在
repositories列表中,包括你用的镜像地址 - 别只关不补:关掉 packagist 后,务必把镜像作为
composer类型仓库加进去,否则require laravel/framework这种基础包会直接失败 - 这个配置对性能影响极小,但会让
composer show查不到未显式注册的包,调试时容易误判
为什么换了镜像还是拉不到 dev 分支?
因为大多数国内镜像(包括阿里云、腾讯云)只同步 stable 版本和 tag,不抓取 dev- 前缀分支或 dev-main 这类开发分支——它们默认只镜像 packagist.org 上已收录的 release 记录。
- 想装
"monolog/monolog": "dev-feature/log-context",必须用vcs仓库直连源 Git 地址 - 镜像的
composer.json里通常有"packagist": false,所以即使你写了镜像 URL,Composer 也不会去它那儿找 dev 分支 - 临时解决办法:
composer require monolog/monolog:dev-main --repository-url=https://github.com/Seldaek/monolog.git,但长期应把该 vcs 地址写进repositories
repositories 的顺序和类型就得手动手动对齐,不能指望一个 config 命令全搞定。










