唯一稳定可用的命令是 composer show -t(2.5+)或 composer show --tree(2.0–2.4),必须基于已安装状态查;不加 . 仅输出顶层包名,加 . 才展开完整依赖树,且需 vendor/ 已安装、composer.lock 存在。

直接结论:别用 composer tree 或 composer depends,它们要么不存在、要么默认禁用且行为不可靠;唯一稳定可用的命令是 composer show -t(Composer 2.5+)或 composer show --tree(2.0–2.4),但必须基于已安装状态查 —— 没装进 vendor/ 就看不到。
为什么 composer show -t 必须带点号(.)
不加 . 时,composer show -t 默认只输出顶层包名,不展开任何依赖树。它把 . 当作“当前项目”这个虚拟根包来解析整条链路。
-
composer show -t .:完整树(含所有已安装的require和require-dev包) -
composer show --no-dev -t .:排除开发依赖,更贴近生产环境(注意--no-dev必须放在-t前面,否则被忽略) -
composer show -t guzzlehttp/guzzle:只展开该包及其下游,适合排查子依赖爆炸问题 - 如果输出只有一行(如
your-project-name dev-main),说明vendor/为空或composer.lock缺失,先跑composer install
composer show -t 输出里重复出现同名包,是不是冲突了
不是必然冲突。缩进层级只表示 require 声明路径,不代表版本不一致。关键看末级括号里的实际安装版本,例如:
工作流任务拆解与模型编排技能。使用场景:(1) 收到复杂工作任务需要拆解为可执行步骤,(2) 需要为不同步骤选择最合适的模型,(3) 需要跟踪工作流进度和模型使用情况,(4) 长时间任务卡住需要问题诊断和解决方案。
- 一处显示
symfony/console v6.2.10,另一处显示symfony/console v5.4.32→ 真冲突,composer.lock可能未同步或存在强制降级 - 两处都标
[v6.2.10]→ 同一版本被多个上游引入,无问题 - 某包只在树中出现、但
vendor/symfony/console目录不存在 → 它只是“曾被请求”,并未真正安装 - 终端宽度不够会导致换行错位,缩进视觉混乱:建议加
| less -S或重定向到文件查看
怎么反向查“谁把我拉进来的”,并确认源头是你自己写的 composer.json
别硬扫几百行树,也别信 composer depends —— 它对 provide、replace、本地 path 仓库支持差,容易漏判。
-
composer why psr/log:返回一级上游(如laravel/framework) -
composer why --tree psr/log:必须加--tree,才能看到完整路径,末尾出现your-project-name dev-main才算确认是你自己写的require -
composer show --who psr/log:扫描所有已安装包的require字段,结果更确定;加--no-dev可过滤开发期依赖 - 若
composer show --who返回空,不代表没人用 —— 可能是某个包通过provide: "psr/log-implementation"虚拟提供,此时应回头看composer show -t .全局结构
什么时候必须放弃文本树,转用 Graphviz 可视化
当 composer show -t . 输出超过 200 行,或嵌套深度 >6 层时,人工读缩进极易误判。这不是你眼力问题,是工具设计限制。
- Composer 没有内置出图命令:
composer graph、composer viz一定会报Command not defined - 可靠方案是导出 JSON 数据再生成 DOT 图:
composer show --format=json --recursive,但要注意:它只读vendor/composer/installed.json,不包含未安装包 - CI/CD 中脚本化分析时,这是唯一可控路径;本地快速诊断仍优先用
composer show -t配合grep过滤,例如:composer show -t . | grep -A3 -B3 "monolog"
最常被忽略的一点:composer show -t 读的是 vendor/composer/installed.json 和 composer.lock 的真实快照,不是 composer.json 里写的“理想状态”。改了 composer.json 但没 update,树还是旧的 —— 这个差异本身,就是多数冲突的起点。

















