provide 字段必须写在被 require 的包中才有效,根项目 composer.json 中声明无效;它仅影响依赖解析阶段,不参与自动加载或运行时校验,需配合正确 autoload 和接口实现。

provide 字段必须写在被 require 的包里,根项目写无效
你本地项目的 composer.json 里加 "provide" 完全没用——Composer 只读取「被其他项目依赖的包」中的 provide 声明。也就是说,只有当你把这个包发布到 Packagist 或私仓、并被别人 require 时,provide 才参与依赖解析。
常见错误包括:
- 在自己项目的
composer.json里写"provide": {"psr/log-implementation": "*"},以为能“让框架认出我的 Logger 类”——不会生效 - 把
provide和replace混用,比如想替代monolog/monolog,结果只写了provide,没写replace,框架仍会装 Monolog - 包未声明
autoload,即使provide正确,类也加载不到,运行时报Class not found
虚拟包名不能自创,得按 PSR 或主流生态约定来
写 "provide": {"my-cache-driver": "*"} 是无效的——Composer 不识别这个名字,其他包 require 它时根本找不到匹配项。必须用已被广泛接受的虚拟包名,例如:
-
psr/cache-implementation:任何实现PsrCacheCacheInterface的包都该提供它 -
psr/http-client-implementation:Guzzle、Symfony HttpClient、HTTPlug 都提供这个 -
psr/log-implementation:Monolog、PsrLogAdapter、甚至一个三行代码的空实现都能提供 -
ext-redis或ext-gd:声明 PHP 扩展可用,供其他包做条件依赖(如某包只在有ext-redis时才启用缓存)
注意拼写细节:psr/cache-implementation ≠ psr/cache(后者是接口规范包,不可被提供);psr/http-client-implementation 末尾是 -implementation,不是 -interface。
版本号写 "*" 最安全,别乱填具体约束
provide 的值是版本约束,不是你实现的 PSR 版本。写 "psr/cache-implementation": "^3.0" 并不表示你实现了 PSR-6 v3,只是告诉 Composer:“我声称兼容满足 ^3.0 约束的任意消费者”。但 Composer 不校验你的代码是否真符合,运行时出错没人兜底。
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
所以建议统一用 "*",除非你明确知道某个消费者强制要求特定版本约束(极少见)。示例正确写法:
{
"name": "acme/redis-cache",
"provide": {
"psr/cache-implementation": "*",
"ext-redis": "*"
},
"autoload": {
"psr-4": { "Acme\Cache\": "src/" }
}
}
provide 不触发自动加载,也不保证运行时行为
这是最容易忽略的一点:provide 只影响 Composer 的依赖安装阶段,和运行时零关系。它不注册自动加载、不校验接口实现、不检查方法签名、不拦截调用。
换句话说:
- 你提供了
psr/log-implementation,但没在autoload里配好LoggerInterface实现类路径 → 运行时报Class not found - 你提供了
psr/http-client-implementation,但send()方法返回数组而非PsrHttpClientClientInterface要求的ResponseInterface→ 运行时类型错误,Composer 完全不管 - 两个包都提供
psr/cache-implementation,Composer 安装时选了 A,但框架初始化时硬编码用了 B 的类名 → 直接崩,和provide无关
真正起作用的是 autoload + 接口契约 + 框架的运行时适配逻辑。provide 只是让 Composer 允许你进安装门,进门之后走错房间,它不负责领路。

















