执行 composer show -d 显示全局依赖而非当前项目依赖,是因为未在项目根目录运行或误用 -d 参数;正确做法是先 cd 进入含 composer.json 的目录,再执行 composer show --installed --direct 查直接依赖。

composer show -d 为什么显示的不是当前项目依赖
执行 composer show -d 时,如果输出的是全局 Composer 配置目录(如 ~/.composer)下的包,说明你没在项目根目录运行命令。Composer 默认以当前工作目录为项目上下文,-d 参数虽可指定目录,但容易误用或遗漏。
正确做法是:先 cd 进入项目根目录(含 composer.json 和 vendor/),再运行:
composer show --installed --direct
这个命令只列出当前项目直接声明的依赖(即 composer.json 中的 require 项),排除了传递依赖,是查“重复安装”起点。
如何识别同一包被多次 require 到不同版本
重复安装通常指:同一个包名(如 monolog/monolog)在 composer.json 中被多个地方显式声明,或通过不同路径引入冲突版本,导致 vendor/ 中实际存在多份副本(极少见),更常见的是 Composer 自动降级/升版后残留旧版本缓存或 lock 文件不一致。
真正要查的是“哪些包被多个依赖间接拉入、且版本不兼容”,可用:
composer depends <package-name></package-name>
例如:composer depends monolog/monolog,会列出所有直接或间接依赖它的包。如果输出里出现多个一级依赖(比如 laravel/framework 和 symfony/console 都依赖它),说明它是共享依赖,不是“重复安装”,而是正常复用。
真正危险的重复信号是:
-
composer install报错Root composer.json requires ... but ... is locked to ... -
composer.lock中同一包名出现多个条目(手动打开 lock 文件搜索包名) -
vendor/下某包目录里有composer.json的version字段和composer.lock记录不一致
composer why-not 能不能用来定位冲突源头
composer why-not 不是用来查重复,而是验证“为什么某个版本无法被安装”。比如你想装 phpunit/phpunit:^10.0 却失败,运行:
composer why-not phpunit/phpunit:10.0
它会输出阻断原因,例如:laravel/framework v10.10.0 requires phpunit/phpunit ^9.5 —— 这说明冲突来自顶层依赖约束,而非重复安装。
所以别指望它发现“重复”,但它能帮你确认:某个包是否因多个父依赖提出矛盾要求而被迫降级,这种降级可能导致本该统一的子依赖实际加载了不同版本(如两个组件分别拉 guzzlehttp/guzzle 的 7.x 和 8.x),这才是运行时潜在问题。
用 composer outdated + 自定义脚本快速扫描可疑包
composer outdated 默认只显示可升级的包,但加 --direct 可聚焦于你亲手写的 require 条目;加 --minor-only 或 --patch-only 能看出哪些包长期未更新,可能因手动修改过 composer.json 导致版本锁定混乱。
更实用的是结合 composer show --tree 手动排查:
composer show --tree | grep -E "^[a-z]+/[a-z]+.*[0-9]+\.[0-9]+\.[0-9]+"
这会把依赖树转成扁平列表,再用 sort | uniq -c | sort -nr 统计同一包名出现次数(注意:同一包名不同版本算不同行)。但要注意——Composer 正常情况下绝不会在 vendor/ 中放同一包的多个版本,所谓“重复”几乎都源于 lock 文件残留、require 冲突未 resolve、或开发中误删 vendor 后部分重装。
最稳妥清理方式永远是:
- 删掉
vendor/和composer.lock - 运行
composer install重新生成干净依赖树 - 再用
composer show --installed --direct对照原始composer.json,看是否有意外增减
真正的重复安装极少发生,更多是开发者误以为“看到两次包名就是重复”,其实只是依赖图里多条路径指向同一个包——那是 Composer 的优化,不是 bug。











