“merge conflict in composer.json”不是Git冲突,而是Composer运行时发现composer.json与composer.lock不匹配或多个依赖争用同一字段;应删lock重装、用require/config命令修改、禁手写JSON合并。

“merge conflict in composer.json”不是 Git 冲突,而是 Composer 自己发现配置不一致 —— 删 composer.lock 重装、用 composer require 或 composer config 修改字段、别手写 JSON 合并。
为什么 composer.json 报 “merge conflict” 却不是 Git 冲突
这个提示来自 Composer 运行时校验,不是 Git。它意味着:composer.json 和 composer.lock 的内容不匹配,或多个依赖(比如两个插件)同时试图修改同一字段(如 autoload 或 scripts),导致 Composer 无法确定最终结构。
- 常见诱因:团队成员各自运行
composer require xxx后只提交了composer.json,没跑composer update或composer install更新composer.lock - IDE 插件或 CI 脚本直接写入 JSON,绕过 Composer 内部逻辑,导致
extra、config等字段被清空或覆盖 - 手动合并
composer.json时改错 JSON 格式(比如多逗号、少引号),composer validate会报JSON decode error
怎么安全合并多人改过的 composer.json
别打开编辑器手动拼 JSON —— Composer 不理解“保留 A 的 require + B 的 scripts”,它只认最终合法结构。正确做法是让 Composer 自己生成。
- 先用
git merge或git rebase合并composer.json,解决文本冲突(这时才是真 Git 冲突),确保语法合法、无重复键 - 运行
composer validate --no-check-publish检查字段合法性,重点看require、autoload、scripts是否在顶层、格式是否合规 - 删掉
composer.lock,再执行composer install—— Composer 会按当前composer.json全量重建 lock 文件和 vendor - 如果只是加了 dev 依赖(如
phpunit/phpunit),优先用composer require --dev phpunit/phpunit,而不是手写进require-dev数组
autoload 冲突:类找不到或 Warning: Ambiguous class resolution
多个包(包括你的项目)都声明了 psr-4 或 files,Composer 会叠加加载路径,但顺序错乱或命名空间重叠就会出问题。
- 运行
composer dump-autoload -v,看输出里是否出现Warning: Ambiguous class resolution—— 这说明同一个类名在多个路径下被定义 - 避免在主
composer.json的autoload.files里硬塞第三方functions.php;应让包自己通过其内部autoload控制加载 - 若必须接管某包的加载逻辑,用
autoload-dev+exclude-from-classmap显式排除其目录,再用自己的规则注册 - PSR-4 支持多路径:
"App\": ["src/", "tests/app-src/"],比拆成多个 JSON 文件更可靠
别再用 composer-merge-plugin
这个插件早在 2019 年停止维护,与 Composer 2.2+ 不兼容,启用后会出现静默失效、autoload 丢失、require 被覆盖等问题,且官方已明确不支持。
- 错误现象:
Plugin merge-plugin could not be initialized,或composer dump-autoload失败但无提示 - 替代方案只有两种:把共享配置抽成私有
metapackage,其他项目require它;或在 CI/CD 中用脚本(PHP / jq)读取多个 JSON 合并为单个composer.json,再执行composer install - CI 脚本生成的
composer.json**不能提交进 Git**,只作为临时构建产物 - 环境差异化需求(如本地加 xdebug)应通过
COMPOSER_ROOT_VERSION或自定义环境变量控制,而非拼配置文件
最易被忽略的一点:composer.lock 是构建指纹,不是配置文件;它的唯一可信来源是 Composer 基于当前 composer.json 的完整重算 —— 任何手动干预都会破坏可复现性。


















