composer show 是确认包是否真实安装的最快方法,它直接读取 vendor/composer/installed.json 列出所有已安装包,不依赖 composer.lock 或网络,结果即事实。

直接运行 composer show 最快确认已安装包
在项目根目录执行 composer show,它会实时读取 vendor/composer/installed.json,列出所有当前真实存在于 vendor/ 中的包(含版本号和描述),不依赖 composer.lock 是否同步。如果某个包没出现在输出里,说明它确实没装上——不是“声明了但没 install”,就是被 composer remove 或手动删掉了。
- 输出为空?先确认是否在正确目录(有
composer.json和vendor/) - 看到包名但版本异常(如
dev-main)?可能是从 Git 仓库安装的开发版,不是稳定 release - 想快速过滤,直接加
| grep "guzzle"或| grep -i "log"
composer show vendor/package 查单个包是否存在且可用
比起扫全量列表,查具体包更精准。运行 composer show monolog/monolog,若返回详细信息(版本、依赖、许可证等),说明已安装且可加载;若报错 Package "monolog/monolog" not found,就是真没装——注意:这和 composer require 失败是两回事,后者可能是网络或版本冲突,而这个错误只反映本地 vendor/ 状态。
- 该命令不走网络,纯本地判断,快且可靠
- 包名必须写全(
vendor/name格式),monolog单独写会失败 - 如果项目用了
--no-dev安装,require-dev里的包不会出现在结果中
用 composer show --direct 区分“声明了”和“实际装了”
很多人误以为 composer.json 里写了就等于装上了。其实 composer show --direct 只列你手动 require 或 require-dev 的包,但它依然只显示“已安装的直接依赖”。换句话说:如果输出里有 laravel/framework,说明它不仅声明了,而且 vendor/ 里真有;如果没出现,要么没 require,要么 composer install 没跑成功,或者被 remove 过。
- 对比
composer show --direct和composer show --tree | head -20,能看出哪些包是“被带进来的” - CI 脚本里做断言时,建议用
composer show --direct | grep -q "package-name",比解析 JSON 更轻量 - 别依赖
composer.lock内容判断——它可能 stale,show才是事实来源
composer why 是验证“为什么装了”的终极手段
有时候一个包明明没在 composer.json 里声明,却出现在 composer show 结果中。这时运行 composer why package/name,它会告诉你谁拉进了它,比如 laravel/framework v10.48.12 requires package/name (^2.0)。这能帮你确认:它不是孤儿包,而是被某个顶层依赖间接引入的。
- 返回空?说明该包目前没被任何已安装包依赖——极可能是冗余残留,可安全
remove - 返回多行?说明多个路径都依赖它,删前得评估影响范围
- 注意:
composer why不检查require-dev的传递依赖,除非你没加--no-dev
真正容易被忽略的是:Composer 的“已安装”状态只看 vendor/ 目录是否存在对应文件夹和 installed.json 条目,和 composer.lock 的声明、composer.json 的内容、甚至 Packagist 上是否存在,都没直接关系。所以别猜,show 一下最省事。










