provide字段必须写在被require的独立包的composer.json中才生效,项目根composer.json里声明会被忽略;需使用约定虚拟包名如"psr/cache-implementation": "*",并正确配置autoload。

provide字段必须写在包级composer.json顶层
根项目(即你本地项目的composer.json)里写的provide会被Composer完全忽略——它只认被其他包require的包所声明的provide。也就是说,只有当你把代码打包成一个可被require的独立包(比如myorg/my-cache-driver),并在它的composer.json里写provide,这个声明才生效。
常见错误包括:
- 在自己项目的
composer.json里加"provide": {"psr/cache-implementation": "*"},以为能“告诉框架我有缓存实现”——没用,Composer直接跳过 - 把
provide写进require或replaces字段,语法合法但语义错误,等同于没写 - 键名拼错,比如
"psr/cache"(这是接口规范包)→ 正确应为"psr/cache-implementation"
虚拟包名不是随便起的,得按生态约定来
Composer不校验你是否真实现了某个PSR,只靠字符串匹配。所以provide里的包名必须和主流框架、库约定的虚拟包名完全一致,否则没人会require它。
高频可用的虚拟包名有:
-
"psr/log-implementation": "*"—— 任何实现了Psr\Log\LoggerInterface的包都该提供这个 -
"psr/http-client-implementation": "*"—— Guzzle、Symfony HttpClient 都这么写 -
"ext-redis": "7.4.0"—— 声明扩展可用性,供其他包做条件依赖(如"ext-redis": "^5.3 || ^6.0 || ^7.0") -
"laravel/framework": "^10.0"—— 某些Laravel扩展包会require它来触发特定逻辑(注意:这通常需配合replace使用,单靠provide不够)
版本号写"*"最安全,别乱填具体约束
provide的值是版本约束,不是你自己的版本号。写"^3.0"意味着你声称自己兼容PSR-3规范的全部行为,但Composer不会验证;运行时若调用了一个你没实现的方法,就崩。
使用ydata-profiling(前身为pandas-profiling)生成全面的数据质量报告,包含相关性分析、缺失值模式和基数检测。导出交互式HTML仪表板和JSON摘要。
实操建议:
- 绝大多数场景直接写
"*",表示“我提供了这个能力,版本由使用者自己判断” - 如果明确只支持某范围(比如只适配PHP 8.2+的
ext-gd新函数),可写"ext-gd": ">=8.2.0",但要确保环境真满足 - 不要写
"self.version"或变量引用——JSON不支持,会解析失败
provide不解决自动加载,autoload还得单独配
provide只影响依赖解析阶段,告诉Composer“我能当某个虚拟包用”。它不负责类文件在哪、怎么加载。
典型翻车点:
- 写了
"psr/cache-implementation": "*",但autoload没配psr-4映射,用户require后new MyCachePool()直接Class not found - 命名空间末尾漏了反斜杠:
"MyCache\": "src/"✅ vs"MyCache": "src/"❌ - 类文件路径和
psr-4配置不一致,比如"MyCache\": "src/",但MyCachePool类实际放在lib/Pool.php
真正生效的链条是:require → Composer查provide匹配 → 安装包 → 加载autoload → 才能new出实例。少一环,前面全白搭。










