conflict 字段仅在 composer install/update 解析依赖时校验版本冲突,不扫描已安装包或运行时调用;仅支持标准语义化版本语法,忽略分支名、dev-前缀等非稳定标识。

conflict 字段只在安装/更新时生效,不是运行时防护
它不拦截已安装的包,也不检查你代码里实际调用了什么——只在 composer install 或 composer update 解析依赖图时,发现某个包的版本号落在 conflict 声明范围内,才中断并报错。
- 你已经装了
guzzlehttp/guzzle:6.5.5,再加"conflict": { "guzzlehttp/guzzle": "^7.0" },不会报错,也不会卸载旧版 - 只有当你执行
composer require some/package,而这个包或它的子依赖会拉入guzzlehttp/guzzle:^7.2时,才会触发冲突 -
conflict不会回溯校验:已存在的composer.lock不会被重新扫描,除非你跑一次composer update
写法必须用标准版本语法,分支名、dev-前缀全无效
Composer 的冲突匹配只基于稳定版本号(如 2.4.1、^3.0),完全忽略分支名、别名、dev- 前缀等非语义化标识。
- ❌ 错误:
"conflict": { "laravel/framework": "dev-master" }—— 这条永远不会触发 - ✅ 正确:
"conflict": { "laravel/framework": ">=10.25.0 ,或更简洁地" - 支持全部 Composer 版本运算符:
、>=、!=、^、~、*,但别滥用*,比如"monolog/monolog": "*"会禁止所有版本,慎用
conflict 和 require 同时存在时,Composer 会先满足 require,再校验 conflict
这不是“优先级高低”问题,而是解析逻辑顺序:require 定义了必须装什么,conflict 是在此基础上加的一道安检门。如果两者无法共存,就会直接报错。
工作流任务拆解与模型编排技能。使用场景:(1) 收到复杂工作任务需要拆解为可执行步骤,(2) 需要为不同步骤选择最合适的模型,(3) 需要跟踪工作流进度和模型使用情况,(4) 长时间任务卡住需要问题诊断和解决方案。
- 例如你的
composer.json有:"require": { "symfony/console": "^6.2" },同时又写"conflict": { "symfony/console": ">=6.3.0" },Composer 就没法选一个既满足^6.2又避开>=6.3.0的版本——因为^6.2包含6.3.0及以上 - 这种情况下,要么放宽
require(比如改成"symfony/console": "^6.2 ),要么删掉冲突声明,别指望 Composer 自动降级到6.2.12 - 注意:
conflict不会引导 Composer 去找替代路径;它只是“不许过”,不是“请绕行”
platform 冲突(如 php、ext-*)受 config.platform 影响,真实环境可能被掩盖
你写了 "conflict": { "php": ",但项目根目录的 composer.json 中设了 "config": { "platform": { "php": "8.1.0" } },那这条冲突就失效了——Composer 会假装运行在 PHP 8.1,不再校验真实 CLI 版本。
- 要让 PHP 版本冲突真正起作用,得确保没配
config.platform.php,或者把config.platform-check设为true(默认开启),它会在install后额外检查真实环境 -
ext-redis、lib-curl等同理:它们的冲突声明只在平台检查环节生效,且完全无法覆盖运行时行为(比如扩展已加载但函数被禁用) - 如果冲突只发生在特定扩展启用时(如
ext-redisvsext-predis),conflict无能为力,必须靠运行时检测或文档警告
require-dev 里,它根本不会参与生产环境的依赖解析。










