composer update 默认更新 composer.json 中 require 和 require-dev 下所有声明的包及其全部子依赖,但严格受限于版本约束,不会跨主版本升级;需配合 composer outdated 检查、--with-all-dependencies 确保依赖树一致性,并执行 composer dump-autoload -o 刷新自动加载。

直接运行 composer update 确实会更新所有包,但它不是“保持最新状态”的安全手段——它重算整个依赖图、改写 composer.lock、可能引入不兼容变更,且无法绕过你写的版本约束。
composer update 默认到底更新哪些包
它会更新 composer.json 中 require 和 require-dev 下声明的所有包(及其全部子依赖),但严格受限于你写的版本约束。例如:"monolog/monolog": "^2.9" 最多升到 2.10.3,绝不会进 3.0.0;"laravel/framework": "9.*" 就卡死在 9.x 分支内。
- 不跳过
require-dev包,测试工具如phpunit/phpunit也会被刷新 - 不会主动放宽约束,哪怕新主版本已发布,它也视而不见
- 若某个包当前已满足约束(比如 lock 里是
2.9.2,约束是^2.9,最新是2.9.3),它就会升;若最新是2.10.0也符合,那就升到2.10.0
想看哪些能升、哪些是破坏性更新,先跑 composer outdated
composer outdated 是唯一靠谱的前置检查命令。它列出所有有新版本的包,并用 ! 标记主版本跃迁(如 symfony/console 从 5.4 → 6.0),这类必须人工核验兼容性。
- 加
--direct只看你在composer.json里直接写的包,忽略间接依赖 - 加
--minor-only过滤掉带!的项,聚焦小版本补丁 - 输出里没标
!不代表绝对安全——某些小版本可能删了方法或改了行为,得看 CHANGELOG
真要批量更新全部,必须加 --with-all-dependencies
空参数运行 composer update 虽然更新全部,但子依赖可能被旧 lock 条目锁住,导致部分包升级后运行时报错(比如类型不匹配、方法不存在)。加 --with-all-dependencies 才会让 Composer 递归重算整棵树中所有已安装包的兼容版本。
- 它仍受
composer.json约束限制:改了"laravel/framework": "^9.0"就不会升到 v10 - 性能代价明显:依赖多、约束杂时,SAT 求解可能卡住几十秒甚至几分钟
- 务必先备份:
cp composer.lock composer.lock.bak,出问题秒还原 - 别用
rm -rf vendor && rm composer.lock && composer install代替——这等于放弃 lock 文件的历史一致性,CI 构建不可重现
升级后类找不到?大概率 autoload 没刷新
这是最常被跳过的一步。composer update 不自动触发自动加载重建,尤其当包结构变动(如新增命名空间、移动文件)时,Class not found 错误几乎必然出现。
- 立刻执行:
composer dump-autoload -o(-o表示优化,生成 class-map) - 如果用了 PSR-4 自动加载,且目录结构没变,不加
-o也能跑,但性能差 - 某些框架(如 Laravel)还要求额外清缓存:
php artisan config:clear、php artisan cache:clear,但那不属于 Composer 职责范围
真正麻烦的从来不是命令敲错,而是版本约束是否合理、间接依赖有没有被隐式拖累、以及升级后是否漏掉了 autoload 刷新或框架缓存清理。











