composer show 默认不显示 provide 字段,需用 composer info vendor/package-name --format=json 或 composer show --all(≥2.5)查看;provide 声明须在被 require 的子包中生效,根项目声明无效,且仅参与依赖解析判断,不强制安装。

composer show 能不能看到 provide 声明
composer show 默认不显示 provide 字段内容,它只列出已安装包的 name、version、type 和 description。即使你在 composer.json 里写了 "provide": {"psr/log-implementation": "*"},执行 composer show vendor/package-name 也不会把这行打出来。
真正能暴露 provide 的命令是:composer show --all(需 Composer ≥ 2.5)或更直接的 composer info vendor/package-name --format=json。后者输出完整 JSON,你能一眼找到 provide 键值对。
为什么 composer why 不会因 provide 而命中依赖
composer why psr/log-implementation 返回空,不代表没人“提供”它——而是 why 只查显式 require 或传递 require 的包,不追踪虚拟包满足逻辑。
要验证某个虚拟包是否被满足,得换思路:
- 运行
composer depends psr/log-implementation,如果返回结果为空,说明当前没有包声明 require 它; - 若你期望某包(如
monolog/monolog)被当作实现加载,但实际没生效,问题往往出在:该包未安装,或它的provide声明版本不匹配你其他包的require约束(比如你require了"psr/log-implementation": "^1.0",而 monolog 声明的是"psr/log-implementation": "2.0.0"); -
composer install -v启动时会打印 “Resolving packages…” 阶段的虚拟包匹配日志,留意类似Found package providing psr/log-implementation: monolog/monolog (2.13.0)的行。
provide 声明写错的常见表现
最典型的错误现象是:明明写了 "provide": {"psr/cache-implementation": "*"},但装另一个 require psr/cache-implementation 的包时,Composer 还是去拉 symfony/cache 或 doctrine/cache。
原因通常有三类:
-
provide写在了子包(非根项目)的composer.json里,但该子包根本没被 require 进来; - 键名拼错,比如写成
"psr/cache"而不是标准名"psr/cache-implementation"; - 值写成了具体版本号(如
"1.0.0"),而依赖方要求的是^2.0,版本不兼容导致无法匹配。
注意:provide 必须放在根项目的 composer.json 顶级字段中才对整个依赖图生效;子包里的 provide 只影响它自己被引用时的行为。
如何确认虚拟包已被满足
最稳妥的方式不是看声明,而是看锁文件和实际安装结果:
- 检查
composer.lock里packages数组下是否有你期望提供能力的包(比如monolog/monolog),且它没被标记为replace或conflict; - 运行
composer show --platform,它会列出所有“平台包”和“虚拟包实现”,其中psr/log-implementation这类会显示为monolog/monolog (2.13.0)—— 这才是最终生效证据; - 如果
composer show --platform输出里某虚拟包对应[none],说明没有任何已安装包成功声明提供它,哪怕你的composer.json里写了provide,也因未安装或版本不匹配而失效。
provide 是声明性机制,不强制安装,也不自动触发下载;它只在依赖解析阶段参与“满足判断”。写对了不一定起作用,得让那个提供者真正在 vendor 里落地才行。











