Composer 通过 composer depends(或 composer why)命令可反向查询某包被谁依赖,如 composer depends psr/log 显示上游依赖链,加 --tree 展开层级,--with-dependencies 包含 dev 依赖;若为空则可能由 replace 或 provide 逻辑提供,需用 composer provides 查。

Composer 不会自动记录“谁用了某个共享依赖”——它只记录安装了什么,不记录为什么装。 你想知道 psr/log 是被 monolog/monolog 拉进来的,还是被你自己显式 require 的?默认情况下,composer show 和 composer install 都不会告诉你。得用专门命令反向查。
composer depends 能告诉你谁依赖了某个包
这是最直接的方式:它列出所有正向拉入该包的上游依赖(包括你的项目本身)。
-
composer depends psr/log—— 显示哪些包声明了对psr/log的require - 加
--tree可展开层级:composer depends --tree psr/log,看到your-project → monolog/monolog → psr/log这样的路径 - 注意:它只查
require,不查require-dev;如需包含开发依赖,加--with-dependencies - 如果输出为空,说明该包是通过
replace或provide“逻辑提供”的(比如monolog/monolog提供psr/log-implementation),这时要用composer provides psr/log
composer why 和 composer why-not 用于诊断用途
composer why 是 depends 的快捷等价命令,语义更明确;composer why-not 则用于排查“为什么某版本装不上”,间接暴露依赖链中的冲突点。
-
composer why guzzlehttp/guzzle等价于composer depends guzzlehttp/guzzle -
composer why-not phpunit/phpunit:10.0会输出类似 “your-projectrequiresphpunit/phpunit ^9.6” 的拒绝原因,从而反推你项目里哪条约束锁死了它 - 这两个命令都依赖当前
composer.lock或已解析的依赖图,若刚初始化项目还没install,可能返回不完整结果
composer tree --format=json 适合脚本化分析用途
如果你需要程序化提取“某个包被谁用、在第几层、是否为 dev-only”,--format=json 比树形文本更可靠。
-
composer tree --format=json | jq '.[] | select(.name == "psr/log") | .requires'(配合jq)可筛出直接依赖它的包列表 - JSON 输出字段含
name、version、requires(该包自己的依赖)、type(如library或metapackage),但不包含“谁引入了它”——这仍是反向关系,得靠depends补全 - 旧版 Composer(--format=json,只能用
composer show --tree,但它混入require-dev且无结构化输出,容易误读
真正容易被忽略的是:Composer 的“用途记录”本质是动态推导的,不是静态存档。每次 composer update 后,依赖链可能变化;composer.lock 只存版本快照,不存决策依据。所以别指望靠一个文件回溯“当初为什么加这个包”,得结合 Git 历史看 composer.json 修改记录 + 当时的 composer why 输出快照。











