composer why 查看包被安装的原因,如 monolog/monolog 因 symfony/console 和项目自身依赖被引入;composer why-not 诊断无法安装原因,如 guzzlehttp/guzzle:8.0 因版本约束冲突被阻止。

当你在使用 Composer 管理 PHP 项目依赖时,经常会遇到某个包被安装了,但你不清楚它为什么会被引入;或者你想安装某个包却失败了,提示冲突。这时候,Composer 提供的 why 和 why-not 命令就非常有用,能帮你快速诊断依赖关系背后的原因。
composer why:查看某个包被安装的原因
这个命令用来查看某个包为何存在于你的项目中——也就是说,它是被哪个包(或项目本身)依赖而被安装的。
语法:composer why vendor/package
例如,你想知道 monolog/monolog 为什么被安装:
composer why monolog/monolog
输出可能类似:
- symfony/console requires monolog/monolog (^2.0)
- your-project requires monolog/monolog (^1.25 || ^2.0)
这说明 monolog/monolog 被安装,既是因为你自己项目 composer.json 中声明了依赖,也是因为 symfony/console 需要它。
你还可以加上 --tree 参数来查看更清晰的依赖树结构:
composer why monolog/monolog --tree
输出会以缩进形式展示谁依赖了谁,便于理解层级关系。
composer why-not:诊断无法安装某个包的原因
当你想安装一个包却失败时,可能是版本冲突、PHP 版本不支持,或其他依赖限制。这时用 why-not 可以告诉你“为什么不能装”。
composer why-not vendor/package:version
例如,你想安装 guzzlehttp/guzzle:8.0 却失败了,可以运行:
composer why-not guzzlehttp/guzzle:8.0
输出可能显示:
- your-project requires guzzlehttp/guzzle ^7.0
- some-package/some-lib requires guzzlehttp/guzzle ^7.2
这说明当前项目或某个已安装的包只允许 Guzzle 7.x,因此 8.0 被阻止。
它还可能提示 PHP 版本问题:
- packageA/packageB 7.0 requires php >=8.1 — your PHP version is 8.0.28
这样你就知道需要升级 PHP 或调整依赖策略。
实用技巧
- 命令对大小写敏感,确保包名格式正确(通常是小写)。
- 可以省略版本号,默认会分析最新稳定版是否可安装。
- 结合
--recursive使用(部分版本支持),可深入查找间接冲突。 - 在 CI/CD 或调试他人项目时特别有用,快速定位“为什么有这个包”或“为什么不能升级”。
基本上就这些。合理使用 why 和 why-not,能让你在处理复杂依赖时少走弯路,快速找到根源。










