composer不会自动合并多个composer.json文件;所谓“merge conflict”实为composer.json与composer.lock不匹配或配置被覆盖,需用composer require/config命令修改、删lock重建,禁用已废弃的merge-plugin。

Composer 不会、也不能安全合并多个 composer.json 文件——所谓“合并冲突”,95% 是误判或错误操作导致的配置不一致,不是 Git 冲突,也不是 Composer 本意支持的场景。
“merge conflict in composer.json”根本不是 Git 冲突
这个提示常出现在 composer install 时,但它和 git merge 无关。Composer 自己检测到 composer.json 和 composer.lock 的内容不匹配,或多个依赖通过 extra、autoload 等字段间接修改了同一配置段(比如两个包都试图往 autoload.files 里加文件)。
- 先运行
git status确认:如果composer.json和composer.lock都是 clean,那问题出在 Composer 内部状态不一致,不是 Git - 如果只是
composer.lock过期(比如别人composer update后没提交 lock),直接删掉它再跑composer install即可重建 - 如果
composer.json真被多人改过(比如两个 PR 都加了require-dev),别手动合并 JSON——用composer require --dev xxx或composer config命令追加,让 Composer 自己维护结构合法性
composer.lock 冲突必须用命令重建,不能手动修
Git 合并时真正容易出冲突的是 composer.lock:它字段多、顺序敏感、含隐式快照(如 content-hash、platform)。手动保留双方或删冲突标记会导致 Your lock file does not contain a compatible set of packages。
- 标准做法:
git checkout --theirs composer.lock && composer install --no-scripts && composer update --lock - 关键点:
--no-scripts避免执行可能失败的脚本;--lock强制重生成 lock 而不改composer.json - CI/CD 中更稳妥:统一用
composer install(不带--no-interaction以外的 flag),确保所有环境从同一份 lock 安装
别用 composer-merge-plugin,它已失效且危险
这个插件早在 2021 年停止维护,与 Composer 2.2+ 不兼容。启用后常见症状包括 autoload 映射丢失、require 被覆盖而非追加、scripts 消失——它的合并逻辑是浅层 JSON 合并,不理解 Composer 的语义规则。
- 报错示例:
Plugin merge-plugin could not be initialized或静默失效 - 替代方案只有两个:
repositories+ 私有包(把共享配置抽成独立包,require它),或用脚本(PHP/jq)在 CI 中动态生成最终composer.json,但绝不提交合并结果到 Git - 若已有项目在用,立刻移除:
composer remove wikimedia/composer-merge-plugin,然后按上述方式重构配置
多环境配置不要拆 JSON,用原生机制收敛
想区分 dev/staging/prod?别搞 composer.dev.json + composer.prod.json 合并——Composer 只读根目录下唯一的 composer.json。
- 开发专用依赖放
require-dev,它默认只在本地生效;生产环境 CI 可用COMPOSER_NO_DEV=1控制 - 平台差异(如 PHP 版本)用
config.platform模拟,避免因本地环境不同导致 lock 不一致 - 动态配置(如 API 密钥)走环境变量,不要塞进
extra字段——很多工具写回composer.json时会丢掉非标准键
最易被忽略的一点:Composer 对 scripts、config、extra 等字段的处理是“全量覆盖”,不是“增量合并”。你手工加的字段,下次 composer require 可能就没了——唯一可靠的做法,是所有配置必须由 Composer 命令驱动,或通过受控脚本生成。











