composer update 默认只更新 composer.json 中直接声明的包,不递归更新子依赖;如需更新子依赖,须显式使用 --with-dependencies 选项,并注意版本约束、锁文件状态及 autoload 是否重建。

composer update 不更新子依赖?默认行为就是“不递归”
执行 composer update 时,它只更新 composer.json 中**直接声明**的包,不会主动升级这些包所依赖的间接依赖(即子依赖、传递依赖)。这不是 bug,是 Composer 的默认保守策略——防止意外破坏兼容性。
比如你写了 "monolog/monolog": "^2.0",而它依赖 psr/log,即使 psr/log 有新 patch 版本,composer update 也不会碰它,除非你显式列出或触发递归更新。
- 想更新某个包及其所有子依赖?用
composer update vendor/package --with-dependencies - 想更新全部直接依赖 + 它们各自的所有子依赖?用
composer update --with-dependencies - 注意:
--with-dependencies不等于 “全量重装”,它仍受composer.json中版本约束限制
为什么 --with-dependencies 有时像没生效?检查锁文件和约束冲突
常见假象是加了 --with-dependencies 却没看到子依赖版本变化。大概率是因为:当前 composer.lock 已满足所有约束,或者子依赖的版本范围太宽(如 ^1.0),而最新兼容版其实没变。
- 先运行
composer show vendor/package看当前安装版本和依赖树 - 再运行
composer depends vendor/subpackage确认谁在引用它 - 如果仍卡住,尝试先删
composer.lock和vendor/,再跑composer update --with-dependencies(仅限开发环境) - 某些子依赖可能被多个顶层包共同约束,Composer 会选一个满足所有条件的版本,未必是最新的
彻底更新 ≠ 强制覆盖:--force-with-dependencies 并不存在
没有 --force-with-dependencies 这个选项。Composer 不提供“无视版本约束强行升到最新”的开关。所谓“彻底”,只能靠组合策略实现:
- 用
composer update --with-dependencies --dry-run预览将更新哪些包 - 对关键子依赖,手动写进
composer.json(如"psr/log": "^3.0"),再composer update - 临时放宽约束:把
"monolog/monolog": "^2.0"改成"monolog/monolog": "*",更新完再调回(慎用) -
--ignore-platform-reqs可绕过 PHP 扩展等环境限制,但不解决依赖版本冲突
更新后 vendor/autoload.php 失效?autoload 未重建是常见盲区
执行完 composer update --with-dependencies 后,如果类找不到,大概率不是依赖没更新,而是自动加载器没刷新。
- Composer 不总在每次 update 后自动 dump autoload,尤其当依赖结构变化不大时
- 务必补一句:
composer dump-autoload -o(-o表示优化,生成 classmap) - 若用了 PSR-4 自定义命名空间,改过
composer.json的autoload段后,这步更是必须 - CI/CD 中容易漏掉这步,导致本地正常、线上报错
Class not found










