执行 composer why vendor/package-name 返回空,主因是该包未安装(不在 vendor/ 中)或仅存在于 require-dev 且未安装开发依赖;需先确认 composer show 是否列出、是否执行过 install/update、是否被 replace/provides 替代。

composer why 为什么找不到包?
执行 composer why vendor/package-name 返回空,不代表没人依赖它——大概率是这个包根本没装进 vendor/,或者只出现在 require-dev 里但你没装开发依赖。
查之前先确认三件事:
-
composer show输出里有没有目标包名(大小写、斜杠方向都要对,monolog/monolog不是monolog\monolog) - 刚改过
composer.json?没composer install或composer update就查不到 - 它是不是被
replace或provides替代了?比如psr/log常被symfony/polyfill-psr-log提供,why不会显示原始引用者
composer why --tree 和 composer show --who 的区别
composer why vendor/package-name --tree 是目前最实用的依赖溯源方式:它从 composer.lock 回溯安装路径,一层层展开,比如 laravel/framework → symfony/console → psr/log → monolog/monolog,能看清它是怎么“被带进来”的。
composer show --who vendor/package-name(≥2.2 支持)更轻量,只列出直接依赖者,不支持 --tree,适合脚本中快速提取包名。但它和 why 一样,只看已安装的包,不扫描代码里的手动 require 或测试文件中的 autoload-dev 引用。
composer depends 命令到底能不能用?
composer depends 在 2.4+ 版本中是实验功能,默认关闭,且官方文档从未正式收录。执行它报错 Command 'depends' is not defined 完全正常——2.3 及更早版本压根没有这个命令。
即使你运行 composer config experimental.show-depends true 启用了它,结果也有限:
- 只查「直接 require 了该包」的顶层包,不递归
- 不区分
require和require-dev - 不显示版本约束(比如是
"^2.0"还是"~1.8")
所以别折腾 depends,老实用 why 或 show --who。
审计时容易忽略的边界情况
依赖审计不是简单跑个命令就完事。以下几点常被跳过,却直接影响结论可靠性:
- 本地没装
--with-all-dependencies?require-dev里的包不会出现在why结果里 - 项目用了
platform配置(如"php": "8.2")?某些包可能因平台约束被跳过,但why不提示这点 - 有自定义
repositories?why查的是composer.lock,如果锁文件里记录的是私仓地址,而你当前配置指向公共源,结果可能不一致
真正要跨项目批量审计(比如查全公司哪些项目还在用 guzzlehttp/guzzle:6.*),硬扛命令行效率极低,得换专用分析工具或写脚本解析多个 composer.lock 文件。


















