--with-dependencies 仅更新目标包及其自身 composer.json 中声明的 require/require-dev 包,不递归处理依赖的依赖;例如 foo/bar 依赖 monolog/monolog,则会按其最新版约束重解析 monolog,但不会动 monolog 所依赖的 psr/log。

composer update --with-dependencies 会更新哪些包
这个参数不是“更新目标包 + 它的直接依赖”,而是“更新目标包 + 所有被该包声明在 require 或 require-dev 中的包(无论当前是否已安装)”。换句话说,它把目标包当作一个“依赖锚点”,拉取其 composer.json 里写的全部依赖项,并按当前 composer.json 的版本约束重新解析、升级或降级。
常见错误现象:composer update foo/bar --with-dependencies 后,monolog/monolog 被升到 v3(你项目没写任何 v3 约束),但你的代码跑崩了——因为 foo/bar 的最新版要求 monolog:^3.0,而 Composer 尊重了它的声明,没管你原来的 monolog:^2.0。
- 只对明确列出的包生效,
composer update --with-dependencies(不带包名)会报错 - 不会递归处理“依赖的依赖的依赖”,只看目标包自己的
composer.json - 如果目标包的依赖和你项目已有约束冲突,Composer 会尝试找交集;找不到就失败,不会跳过
不用 --with-dependencies 也能更新依赖的替代方案
多数时候你真正想要的是“更新 A 包,并让它用上最新兼容的子依赖”,而不是强制对齐它的最新 composer.json。这时更安全的做法是先删掉 vendor 和 composer.lock,再跑 composer install ——但代价大、不可控。
更实用的路径是分两步:
- 先运行
composer update foo/bar(不加参数):只更新foo/bar本身,子依赖保持 lock 文件记录的版本 - 再运行
composer update foo/bar monolog/monolog symfony/event-dispatcher(把你知道它依赖的关键包列出来):让 Composer 重新计算这些包之间能共存的最新版本
这样既避免了 --with-dependencies 的“全盘接管”风险,又比全量 update 快且可预测。
工作流任务拆解与模型编排技能。使用场景:(1) 收到复杂工作任务需要拆解为可执行步骤,(2) 需要为不同步骤选择最合适的模型,(3) 需要跟踪工作流进度和模型使用情况,(4) 长时间任务卡住需要问题诊断和解决方案。
--with-all-dependencies 和 --with-dependencies 的区别
名字像,行为差很远:--with-all-dependencies 是“更新目标包 + 所有它依赖的包 + 这些包依赖的包……一直到底层”,也就是整个依赖树里所有被牵连的包都会被重新 resolve;而 --with-dependencies 只看目标包自己声明的 require 列表。
性能影响明显:--with-all-dependencies 在大型项目中可能卡住几十秒,还容易触发内存溢出(尤其 PHP 内存限制 1.5G 以下时);--with-dependencies 相对快,但依然可能因跨 major 版本升级引发兼容问题。
- 两者都不修改你项目根目录
composer.json的约束,只影响composer.lock - 如果你的
foo/bar依赖guzzlehttp/guzzle,而guzzlehttp/guzzle又依赖psr/http-client,那么--with-dependencies不会动psr/http-client,但--with-all-dependencies会 - PHP 8.1+ 下某些包的 autoloading 行为变化,会让
--with-all-dependencies触发意外的 class not found,尤其涉及psr-4映射变更时
更新前必须检查的三个地方
很多人执行完 composer update foo/bar --with-dependencies 就直接 commit,结果 CI 失败或线上报错。核心问题是没提前确认依赖链的真实影响范围。
- 打开目标包的 packagist 页面(比如 https://www.php.cn/link/a2896cb11aed969ffec7bb02a7c772a8),点开最新版的
composer.json,手动看它的require字段写了什么,特别是有没有php版本限制、ext-*扩展要求 - 运行
composer show foo/bar查当前安装版本,再运行composer depends foo/bar看谁依赖它——避免你更新它导致上游调用方出问题 - 本地改完后,别只跑 PHPUnit:用
composer run-script post-update-cmd(如果定义了)或手动执行php -l扫描所有改动文件,防止语法错误漏过
最常被忽略的是:目标包的某个新依赖可能引入了和你现有包冲突的 PSR 类型(比如两个包都提供 Psr\Log\LoggerInterface 但实现不兼容),这种问题不会在 update 阶段报错,只会在第一次调用时 fatal error。

















