composer show -t 是当前唯一稳定、无需插件、能读取真实安装快照的依赖树命令,必须指定包名(如 . 或 guzzlehttp/guzzle),不加会报错;--tree 参数在 Composer 2.5+ 已移除。

composer show -t 是唯一能立刻跑通的命令
它不是图,但它是你此刻最该用、也唯一不依赖插件就能看到真实依赖快照的命令。别试 composer graph 或 composer viz —— 官方根本没实现,报错 “Command 'graph' is not defined” 不是你配错了,是压根不存在。
composer show -t 的缩进只代表 require 声明层级:每多两个空格,就表示下一层是上一层的直接子依赖。比如 guzzlehttp/guzzle 下缩进出现 psr/http-client,说明 Guzzle 的 composer.json 里明确写了它;同一包在不同缩进重复出现(如 2 级和 4 级),大概率被多个上游包分别引入——这时才真要警惕版本是否一致。
- 必须加点号:
composer show -t .,否则报Not enough arguments -
--no-dev必须放在-t前面,否则无效;不加它,phpunit拉进来的旧版symfony/polyfill会混入生产链路 - 终端宽度太小会导致换行错位,建议管道进
less -S:composer show -t --no-dev . | less -S - 输出中不带版本号,看到
monolog/monolog得再跑composer show monolog/monolog查实际安装版
graphviz + composer-dependency-graph 是最稳的可视化组合
想真正看清谁在控制日志流向、symfony/console 被多少路径引入且版本是否统一,纯文本树已经失效。这时候必须转图,而 markuspoerschke/composer-dependency-graph 封装了数据清洗、DOT 生成、调用 dot 渲染的全流程,比手动拼 composer show --format=json --recursive 再过滤更可靠。
- 全局安装:
composer global require markuspoerschke/composer-dependency-graph - 生成 PNG:
composer graph --filename=deps.png --format=png - 生成可点击 HTML:
composer graph --filename=index.html --format=html --no-dev(注意旧版可能不支持--no-dev,建议用 v2.0+) - 图打不开?双击 HTML 会因 CORS 失效,需起本地服务:
python3 -m http.server 8000,再访问http://localhost:8000/index.html - 图太密?加
--max-depth=2或--filter="laravel/*"限定范围
dot 渲染失败常见原因和绕过方式
dot: command not found 是最常卡住的地方——这不是 PHP 或 Composer 的问题,是系统缺 Graphviz 二进制。它不随 Composer 自动安装,必须单独装。
工作流任务拆解与模型编排技能。使用场景:(1) 收到复杂工作任务需要拆解为可执行步骤,(2) 需要为不同步骤选择最合适的模型,(3) 需要跟踪工作流进度和模型使用情况,(4) 长时间任务卡住需要问题诊断和解决方案。
- macOS:
brew install graphviz(M1/M2 芯片确认dot -V能输出版本) - Ubuntu/Debian:
apt install graphviz - Windows:从 graphviz.org 下载安装包,把
Graphviz/bin加进系统 PATH - 如果
composer graph报Class 'Graph' not found,说明插件依赖未装全,加--no-plugins重试,或手动composer require graphp/graph - 私有包或
"type": "path"引入的本地包,默认不会出现在图中,得靠composer-unused配合--scan-path手动指定目录
依赖图里真正容易被忽略的三类节点
图出来之后,别只盯着布局美观。重点看这三处硬伤,它们往往对应隐性耦合、废包残留或运行时崩溃源头:
- 箭头双向闭环 → 实锤循环依赖,必须砍掉其中一端的
require(比如 A require B,B 又 require A) - 同一包出现多个版本节点(如
guzzlehttp/guzzle:7.4和7.8并存),说明解析器没统一版本,得查composer why guzzlehttp/guzzle看谁在强制降级 - 孤立子图(某组包完全不连主干)→ 很可能是废弃的 dev 包、未被代码引用的包,或
provide/replace导致的虚拟包占位,需结合composer-unused验证是否真被使用
所有图都不反映自动加载顺序,vendor/autoload.php 注册行为由 classmap 和 psr-4 配置决定,和图中箭头方向无关。真正麻烦的从来不是画出一张图,而是读懂那些重叠节点、交叉边、孤立子图背后的真实约束。










