正确命令是composer show --tree和composer why --tree:前者查看已安装包的依赖树(需在项目根目录且vendor存在),后者追溯包引入源头(加--tree才能上溯至your-project-name dev-main);查谁依赖某包用composer show --who,非depends。

别用 composer tree 或 composer depends 盲查——它们要么不存在,要么行为和你想的不一样。 真正能立刻看清依赖结构、定位冲突源头的,只有 composer show --tree 和 composer why --tree 这两个命令,且必须配合明确场景使用。
怎么查“这个包是怎么进来的”
当你看到 vendor/monolog/monolog 被装进项目,但自己没在 composer.json 里写过它,就得搞清来源。直接跑 composer why monolog/monolog 只会返回一级依赖(比如 laravel/framework),根本看不出是不是你自己间接引入的。
- 必须加
--tree:运行composer why --tree monolog/monolog,输出末尾出现your-project-name dev-main才说明源头在你自己的composer.json中 - 若中断在某个包名后没继续(如停在
illuminate/log),大概率是那个包用了provide声明虚拟包(比如提供psr/log),不是真实安装的包 -
composer why默认不看require-dev,要查测试依赖也得加--all
怎么查“谁在用这个包”
想删掉 psr/log?先确认有没有包强依赖它。别用 composer show psr/log——它只显示这个包自己 require 了谁,完全答非所问。
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
- 用
composer show --who psr/log(≥2.2),它列出所有require了它的已安装包,干净无歧义 - 若只想看生产环境(排除
phpunit/phpunit这类 dev 包),加--no-dev参数 -
composer depends是个陷阱:2.4+ 才有,且默认关闭;即使开启,它也不如show --who稳定,官方已明确推荐后者
怎么查“整个项目的依赖长什么样”
composer show --tree 是唯一可靠命令,但它不是“画图工具”,而是输出当前 vendor/ 和 composer.lock 的真实快照,不是 composer.json 的理想状态。
- 必须在项目根目录运行,且目标包得已安装,否则报
Package not found - 想查未安装包的依赖结构(比如评估要不要引入新包),加
--remote:例如composer show --remote --tree monolog/monolog - 它不支持
--depth截断层级,真要控制长度,只能靠head -n 50或重定向到文件后人工筛选 - 别拿它当代码调用分析——依赖树 ≠ 类加载顺序,更不等于运行时方法调用链
为什么 autoload 顺序会影响行为,但依赖树里完全看不到
两个包都声明了 Helper 类,一个在 src/,一个在 lib/,运行时行为突变却查不到原因?因为 Composer 的依赖树根本不记录 autoload 注册顺序。
- 加载顺序由
composer.json中autoload和autoload-dev的声明顺序、各包自身的 autoload 配置共同决定 - classmap 优先于 PSR-4,所以
composer dump-autoload -o生成优化 classmap 后,顺序就固定了 - 调试时可在入口加
echo spl_autoload_functions();查看实际注册的 loader 链 - 检查命名空间冲突:运行
composer show -t,注意同一命名空间是否被多个包同时声明
依赖树只是静态快照,它不反映运行时加载逻辑,也不体现 provide/replace 带来的逻辑替换。真正卡住的时候,往往不是树没看清,而是把“依赖关系”和“类加载行为”混为一谈了。










