composer depends 不可靠,仅扫描项目 composer.json 中显式声明的依赖,不读 vendor 包的 composer.json;查反向依赖应优先用 composer why --tree(需包已安装),或 composer show --who 查直接声明者。

composer depends 不是查依赖链的可靠工具,它只扫描你项目 composer.json 里显式写的 require 和 require-dev,完全不读 vendor 里任何包的 composer.json。
composer depends 为什么经常返回空或报错
它不是“谁在用这个包”的通用答案,而是“谁在 composer.json 里直接写了它”。常见失败场景:
-
Could not find package:90% 是包名输错——monolog/monolog≠Monolog/monolog,斜杠不能省,大小写敏感 -
Command "depends" is not defined:Composer 版本低于 2.5;运行composer --version确认,旧版只能弃用 - 结果为空但
ls vendor/foo/bar存在:说明它是被某个已安装包(比如guzzlehttp/guzzle)作为子依赖带进来的,而那个父包本身没出现在你的composer.json中 - 加了
--dev却没效果:因为--no-dev优先级更高,两者混用时后者会覆盖前者
真正能反向查到源头的命令是 composer why --tree
composer why --tree 才是追踪“谁把我拉进来的”正解,但它有硬性前提:
工作流任务拆解与模型编排技能。使用场景:(1) 收到复杂工作任务需要拆解为可执行步骤,(2) 需要为不同步骤选择最合适的模型,(3) 需要跟踪工作流进度和模型使用情况,(4) 长时间任务卡住需要问题诊断和解决方案。
- 目标包必须已安装到
vendor/下,否则直接静默失败(不是报错,是没输出) - 默认不查
require-dev链路;如果包只被phpunit/phpunit引用,得加--dev - 遇到
provide声明的虚拟包(如psr/log),why --tree可能不显示任何内容——此时要退回到composer show --tree | grep -B2 -A2 "psr/log"手动翻 - 输出末尾出现
your-project-name dev-main,才确认是你自己composer.json里写的require
依赖树里同一包反复出现,到底有没有冲突
缩进不是排版,是声明层级。同一包(如 symfony/polyfill-php80)在不同缩进深度重复出现,只说明它被多个上游包分别引入,不等于装了多份,也不必然冲突:
- 要看实际版本是否一致:运行
composer show symfony/polyfill-php80查真实安装版 - 如果树里显示
guzzlehttp/guzzle下是[7.8.1],而laravel/framework下是[6.5.8],那才是真冲突前兆 -
composer show --tree不显示版本号,只列包名;版本信息必须单独查,不能靠树形输出脑补 - 终端宽度太窄会导致缩进换行错位,建议用
composer show --tree --no-dev | less -S横向滚动看
最易被忽略的一点:vendor/composer/installed.json 是快照,不是权威源——它只反映上一次 composer install 或 update 的结果。改了 composer.json 但没运行更新,树就是过期的;手动删过 vendor/ 里的包,树里却还留着,这种“滞后性”必须时刻心里有数。










