Composer 不支持 peerDependencies 语义,会完全忽略该字段,既不安装也不校验;其依赖求解仅基于 require、require-dev 等显式字段,无运行时强制对齐机制。

Composer 不原生支持 peer 依赖(peer dependencies)语义,它会忽略 peerDependencies 字段,既不安装、不校验、也不参与 SAT 求解。 这是与 npm/yarn 的根本区别——PHP 生态中没有等价的运行时强制对齐机制。
为什么 composer.json 里的 peerDependencies 完全无效
Composer 的包元数据解析逻辑(src/Composer/Package/Loader/RootPackageLoader.php 等)明确跳过 peerDependencies 字段。它只处理:require、require-dev、conflict、replace、provide 等字段。即使你在 composer.json 中手动写入 "peerDependencies": {"psr/log": "^3.0"},Composer 在构建 Pool 或运行 Solver 时根本不会读取它。
常见错误现象:
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
- 你发布了一个库,声明了
peerDependencies,但用户composer require它后没装psr/log,项目却能正常 install —— 因为 Composer 压根不管 - CI 报
Class not found: Psr\Log\LoggerInterface,但composer install成功且无警告 —— peer 缺失未被检测
provide 是最接近 peer 语义的替代方案
如果你希望表达“本包提供某接口能力,使用者需自行确保兼容实现存在”,应改用 provide 字段,并配合 require 或文档约束:
-
"provide": {"psr/log": "3.0.0"}表示:本包自身实现了 PSR-3 v3 规范(或兼容),可作为该能力的提供者 - 但若你**要求使用者必须额外装一个独立实现**(如 monolog),就不能靠
provide,而得在require中显式写明,或靠文档/CI 脚本检查 -
provide会影响依赖求解:当另一个包require了psr/log,而你当前包provide了它,Solver 可能跳过安装真实实现 —— 这和 npm peer 的“必须由消费者装”逻辑相反
实际项目中如何模拟 peer 约束
没有语言层支持,只能靠工程手段补位:
- 在
composer.json的require中写明最小必要 peer 实现(例如"monolog/monolog": "^3.0"),而非留空指望用户自觉 - CI 阶段加校验脚本:用
composer show psr/log --no-ansi 2>/dev/null || (echo 'ERROR: psr/log missing' && exit 1) - 在
README.md和UPGRADE.md中明确标注 “requires PSR-3 v3 implementation”,并列出已验证兼容的包(如monolog/monolog:^3,php-pm/php-pm:^3) - 避免在库代码中直接
new \Psr\Log\LoggerInterface—— 改用构造器注入或容器获取,把实例化责任彻底交给使用者
真正容易被忽略的是:PHP 包作者常误以为 peerDependencies 能起作用,结果在用户环境静默失败。Composer 的设计哲学是“显式优于隐式”,所有参与解析的依赖都必须出现在 require 或其传递链中;任何靠约定、文档或字段名暗示的“间接要求”,都不会进入 Solver 的 CNF 公式。

















