composer show --tree 是查看项目真实依赖树的唯一可靠命令,它基于 vendor/ 和 composer.lock 输出实际安装快照,非 composer.json 的理想状态;需加包名或 grep 过滤才能准确定位。

用 composer show --tree 看真实依赖结构
你写的 composer.json 是愿望清单,composer show --tree 才是你项目里真正长出来的依赖树。它读的是 composer.lock 和 vendor/,不是推测结果。
常见错误是只跑 composer show --tree 不加参数,输出太长且关键信息被淹没。实际要用过滤:
-
composer show --tree | grep "guzzlehttp/guzzle"—— 快速定位某个包被谁拉入、锁在哪个版本 -
composer show --tree monolog/monolog | grep -A5 -B5 "psr/log"—— 查两个包之间的真实传递路径 - 看到某行末尾标着
(locked to 7.8.1)或(replaced),说明这个版本已被固定或替代,不能靠改上层约束绕过
用 composer why-not 定位阻塞源头
报错里出现 don’t install xxx,不是“不能装”,是“装不了”——因为某条依赖链上有人锁死了互斥版本。这时必须用 composer why-not 逆向查。
注意三点:
- 命令必须带完整版本号,例如
composer why-not laravel/framework:11.0.0,不能只写laravel/framework - 输出从下往上读:最上面一行通常是
Root package requires,说明是你composer.json里写了过窄的约束(比如"php": "8.2") - 如果输出为空,优先检查
require-dev—— 很多冲突来自phpunit/phpunit或mockery/mockery拖着老版sebastian/exporter
用 composer update --dry-run -v 暴露隐性约束
普通报错常把真正原因折叠掉。--dry-run -v 不改任何文件,但会完整输出依赖求解过程,重点盯住含 because 的嵌套行。
例如:
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
- Root composer.json requires monolog/monolog ^2.0 → satisfiable by monolog/monolog[2.0.0, ..., 2.10.0].<br>- monolog/monolog 2.10.0 requires php ^7.2 || ^8.0 → your PHP version (8.1.0) does not satisfy that requirement.
这说明问题不在版本号冲突,而在 PHP 版本不兼容——而这个信息在普通 install 错误里根本看不到。
执行时注意:
- 别跳过
-v,没它就看不到because链 - 翻输出末尾 10 行,反复出现的包名(如
symfony/console)大概率是冲突枢纽 - 若发现
Root requirements段落里某行明显过时(比如还写着"laravel/framework": "^9.0"),直接改它
别信 composer depends,它不反映版本限制
composer depends vendor/package 只告诉你“谁依赖它”,但不体现具体版本要求。它无法回答“为什么装不上 3.0.0”,因为不查 requires 字段里的约束范围。
真正有用的命令组合是:
-
composer prohibits vendor/package:^3.0—— 查当前项目里哪些包强制要求旧版,从而封杀 3.x -
composer show vendor/package—— 看它的requires和conflict字段,再和你本地已装版本比对 -
git diff composer.lock—— 对比两次变更,确认到底是哪个包悄悄升级/降级导致了断裂
依赖冲突从来不是单点问题,而是约束网络里的一个断点。越早放弃“删 lock 重来”的直觉,越快找到那个真正卡死的交叉口。










