composer update 默认不升级主版本,受 composer.json 版本约束限制;升主版本需手动修改约束并执行 update,同时注意 lock 文件提交与依赖冲突排查。

composer update 会更新所有包,但默认不升级主版本
直接运行 composer update 确实会重新计算整个依赖图并安装最新兼容版本,但它受 composer.json 中的版本约束严格限制——比如写的是 "monolog/monolog": "^2.0",它永远不会装 3.x,哪怕 3.0 已发布。这不是“没更新”,是“不敢越界”。
常见错误现象:composer update 后 vendor/ 里某包还是旧版,composer show monolog/monolog 显示 2.9.1,而官网已发 3.0.0 —— 这不是命令失效,是版本约束卡住了。
- 想升主版本(如 2→3),必须手动改
composer.json里的约束,比如把"^2.0"改成"^3.0",再composer update monolog/monolog - 全量强制升到允许范围内的最新版(含次版本、修订版),用
composer update --with-all-dependencies,它会递归更新子依赖,避免“半升不升”导致的冲突 - 生产环境切忌无差别跑
composer update,容易因小版本变更引入 BC break;先在 dev 环境跑,再git diff composer.lock看清改了哪些 SHA
只更新某个插件,别漏掉它的依赖树
执行 composer update vendor/package-name 看似精准,但 Composer 默认只更新该包本身,不碰它的子依赖(比如 package-name 依赖 symfony/event-dispatcher ^5.4,而你本地锁的是 5.4.0,它不会自动升到 5.4.26)。
使用场景:修一个插件的安全漏洞,或适配新 API,但又不想牵动整个项目依赖。
- 安全/稳定起见,加
--with-dependencies:composer update guzzlehttp/guzzle --with-dependencies - 如果该插件的子依赖也需同步升到兼容最新版(比如为支持 PHP 8.2),用
--with-all-dependencies - 注意:某些插件的子依赖可能被其他包共同引用,强行升级可能引发冲突,此时
composer why-not vendor/dep能查出谁在拦着它升级
composer outdated 显示的“可升级”不等于“能一键升”
composer outdated 列出所有有新版的包,但它的判断只基于当前约束是否允许升级——如果显示 laravel/framework 9.52.15 → 10.38.1,不代表 composer update laravel/framework 就能成功,很可能因为你的其他包还没适配 Laravel 10,Composer 会直接报错退出。
性能与兼容性影响:盲目按 outdated 提示逐个升级,容易陷入“A 升了要 B 配套,B 升了要 C 改代码”的循环。
- 先跑
composer why-not laravel/framework:10.*,看哪几个包在挡路 - 升级前检查目标包的 CHANGELOG 或 UPGRADE.md(比如 Laravel 10 要求 PHP ≥8.1,且废弃了
App/Providers/AppServiceProvider::boot()里的某些调用) - 对关键框架升级,建议配合
composer update --dry-run预演,确认无冲突再真正执行
lock 文件没提交?那你的“升级”根本不可重现
很多人只改 composer.json、跑 update、测试通过就上线,却忘了 composer.lock 是实际安装依据。没提交它,CI 构建或同事 composer install 时,会按旧 lock 文件装包,结果和你本地完全不一样。
容易踩的坑:Git 忽略了 composer.lock,或 CI 流水线用了 composer install --no-interaction 但没确保 lock 文件存在。
- 每次
composer update后,必须git add composer.lock并提交 - CI 中应始终用
composer install(而非update),它只读 lock 文件,保证环境一致 - 若发现线上行为异常,第一反应不是“代码有问题”,而是
git diff HEAD~1 composer.lock,看最近一次依赖变更动了什么
依赖升级最麻烦的从来不是命令怎么敲,而是搞清“哪个约束在拦路”“谁依赖了谁”“lock 文件有没有同步”。这些细节漏一点,后面几小时都在 debug 为什么本地好使、线上报错。









