“一键升级所有包”不推荐,因等于放弃版本控制权,易引发线上事故;composer update 仅在 composer.json 约束内升级(如 "^2.1" 升至 2.x 最新,不跨主版本),主版本跃迁须手动修改约束并核验。

不推荐“一键升级所有包”——它等于主动放弃版本控制权,99% 的线上事故都从这里开始。
composer update 默认到底升哪些版本?
它只在 composer.json 中声明的版本约束范围内升级,比如 "monolog/monolog": "^2.1",就只会升到 2.x 最新小版本(如 2.10.0),绝不会跨到 3.0.0。主版本跃迁必须手动改约束再运行。
- 运行
composer outdated可直观看到哪些包有更新,带!标记的是主版本变化,需人工核验 -
composer update不跳过require-dev下的包,想省时间加--no-dev - 升级后类找不到?大概率是 autoload 没刷新,立刻执行
composer dump-autoload -o
真要批量更新全部依赖,必须理解 --with-all-dependencies
--with-all-dependencies 不是“无视约束强行全升”,而是让 Composer 递归重算整个依赖树中所有已安装包的兼容版本——仍受 composer.json 约束限制。例如 "laravel/framework": "^9.0",就不会升到 v10。
- 它会让间接依赖(比如你没直接 require、但被其他包拉进来的包)也参与版本重决策
- 依赖多、约束复杂时,SAT 求解可能卡住,比普通
update慢数倍 - 务必先备份:
cp composer.lock composer.lock.bak,出问题秒回退
别用 rm vendor + composer install “假装更新”
删掉 vendor 和 composer.lock 后跑 composer install,看似“全新安装”,实则是让 Composer 从头求解依赖图——结果和 composer update 几乎一致,但丢失了 lock 文件的历史一致性保障,在 CI/CD 中极易引发不可重现构建。
- 正确做法:先
git status确认无未提交变更,再composer update --dry-run预览变更 - CI 流程里误写成
composer update而非install?会导致每次构建拉不同版本,线上行为漂移 -
composer update是一次新的依赖决策,改的是composer.lock,影响所有人
框架主版本升级不能靠命令自动完成
升级 Laravel 9 → 10 或 Symfony 5 → 6 这类操作,composer update 压根不会动——除非你先手动把 "laravel/framework": "^9.0" 改成 "^10.0",再配合官方迁移文档逐项检查。
- 官方迁移向导(如 Laravel Shift)不是可选插件,是必经流程
- 跳过这步直接
update,等于在生产环境埋雷 - 升级后必须跑全量测试,尤其注意
phpunit、symfony/console等工具类包的 API 变更
最常被忽略的一点:Composer 的“升级”本质是重新决策依赖图,不是打补丁。它改的是 composer.lock,而这个文件决定了所有环境的行为一致性——改之前没看 outdated,没备份 lock,没跑测试,就等于把控制权交给了随机性。











