provide字段用于声明本包能替代某虚拟包(如psr/log-implementation),必须写在被require包的composer.json根级,键为packagist注册的虚拟包名、值推荐“*”,修改后需执行composer update --lock生效。

provide 字段不是用来“提供替代包”的声明,而是用来声明“本包能替代某个虚拟包或真实包”的能力;它不自动替换、不控制安装逻辑,只参与依赖解析时的匹配。
provide 字段写在哪才生效
它必须出现在被他人 require 的那个包自身的 composer.json 根层级,和 name、require、autoload 并列。写在你自己的项目根目录 composer.json 里完全无效——Composer 直接忽略。
- ✅ 正确位置:
{"name": "myorg/logger", "provide": {"psr/log-implementation": "*"}, ...} - ❌ 错误位置:
"require": { "provide": { "psr/log-implementation": "*" } }或塞进autoload里 - ⚠️ 修改后必须运行
composer update --lock,否则composer.lock仍按旧声明解析
provide 键名必须精确匹配 Packagist 上注册的虚拟包名
拼错、大小写错误、多空格、用错连字符,都会导致下游 require 失败,且 Composer 不报错,只静默跳过。
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
- ✅ 正确键名:
psr/log-implementation、ext-gd、php-http/client-implementation - ❌ 错误键名:
psr/log(这是真实包)、PSR/Log-Implementation(大小写敏感)、psr/logimpl(不存在) - ? 查证方式:打开 https://www.php.cn/link/f380a1a11b8447811db8d2de62d0e6f3,确认虚拟包是否在官方列表中
provide 值写 * 还是具体版本?
值不是你自己的版本号,而是你所声明实现的那个虚拟包的兼容范围。它参与语义化版本匹配,写错会导致依赖方 fallback 失败或运行时报错。
- ✅ 推荐写法:
"*"(表示“完整兼容该规范任意版本”),或明确范围如"^3.0" - ❌ 禁止写法:
"dev-main"、"latest"、"3.x"、"self.version"—— Composer 解析失败并报Invalid version string - ⚠️ 如果你的实现只兼容 PSR-3 v3,就别写
"*";否则下游依赖 v1 的包可能因方法缺失而崩溃
provide 单独用没法安全替代一个真实包
仅靠 provide 不足以让 Composer 把你的包当原包用。比如想替代 monolog/monolog,只写 "provide": {"monolog/monolog": "2.10.0"} 是不够的:Composer 仍可能同时拉取两者,造成类重复加载或冲突。
- ✅ 安全做法:搭配
replace字段,例如:"replace": {"monolog/monolog": "*"}—— 告诉 Composer “别装它了,我全权代替” - ⚠️
provide声明契约,replace声明排他性;缺一不可 - ⚠️ 虚拟包本身没有代码、不能 autoload、也不能
use;它只是个占位符,不解决运行时类加载问题
最常被忽略的一点是:provide 不校验你是否真有对应接口实现、类是否可 autoload、方法签名是否匹配。它只管“声称”,不管“兑现”。装得进去,跑不起来,才是最麻烦的翻车场景。










