Composer不支持也不该合并多个composer.json文件,它只读取根目录下唯一配置;所谓“合并”实为配置收敛需求,正确解法是用私有包、repositories或环境变量统一管理,而非拼接JSON。

Composer 本身不支持、也不该合并多个 composer.json 文件——你试图“合并”的本质,是配置收敛问题,不是文件拼接问题。
为什么不能直接合并 composer.json
Composer 只读取项目根目录下唯一的 composer.json,它不解析子文件、不识别 composer.dev.json 或 composer.prod.json 这类命名变体。所有“多环境配置合并”诉求,若靠脚本强行拼接 JSON,会踩到这些坑:
-
require字段被浅层合并,导致版本冲突或依赖丢失(比如两个文件都 require"monolog/monolog",但版本不同,array_merge_recursive不做版本兼容判断) -
autoload中的psr-4映射被整个替换而非追加,"App\": ["src/", "tests/app-src/"]这种多路径写法才是正确复用方式 -
merge-plugin已废弃且不兼容 Composer 2.2+,启用后composer dump-autoload可能静默失败,报Class not found却查不到原因 - 一旦
composer.json被覆盖,scripts、extra等手工添加的字段可能被丢弃——Composer 写回时只保留它认知内的顶层键
config 字段不支持局部叠加,只做整块替换
你在项目 composer.json 里写 "config": {"cache-dir": "vendor/cache"},哪怕只改了一个键,也会让全局配置中所有 config 字段(如 bin-dir、process-timeout)彻底失效。这不是“优先级更低”,而是直接丢弃。
工作流任务拆解与模型编排技能。使用场景:(1) 收到复杂工作任务需要拆解为可执行步骤,(2) 需要为不同步骤选择最合适的模型,(3) 需要跟踪工作流进度和模型使用情况,(4) 长时间任务卡住需要问题诊断和解决方案。
- 常见误操作:只在项目里配了
github-oauth,以为其他 config 还能继承全局值 → 实际上全部清空 -
repositories同样整块替换:写了自定义源,Packagist 官方源就没了,必须显式加上{"type": "composer", "url": "https://packagist.org"} -
${VAR_NAME}占位符仅对字符串字段有效;"notify-on-install": "${CI}"会解析失败,因为布尔值不能从字符串强制转换 - 默认值 fallback 必须由 shell 层展开,如
${COMPOSER_TIMEOUT:-300};Composer 自身不处理:-语法,变量未设时直接报错
真正可用的多环境方案只有三类
绕过文件合并,用 Composer 原生机制实现环境差异化:
-
COMPOSER_AUTH环境变量:可完全替代磁盘上的auth.json,接受 JSON 字符串,适合 CI 注入私仓凭据,例如export COMPOSER_AUTH='{"http-basic":{"repo.example.com":{"username":"$USER","password":"$TOKEN"}}}' -
config.platform+ 环境变量:在composer.json中声明"platform": {"php": "${PHP_VERSION}"},再由 CI 设置PHP_VERSION=8.2,让依赖解析锁定平台版本 - 外部脚本动态生成:用 PHP 或 jq 读取
common.json和prod.json,执行array_merge_recursive后写入临时composer.json,再运行composer install;注意要校验最终文件的composer validate --no-check-publish
别忽略 COMPOSER_HOME 和 PATH 的路径陷阱
很多人设了 composer config --global github-oauth.github.com xxx,也能成功 composer global require,但敲 think 就报“不是内部或外部命令”。这不是配置没生效,而是 COMPOSER_HOME 指向错误或 PATH 没包含 COMPOSER_HOME/bin。
-
COMPOSER_HOME必须是绝对路径,不能含~、$HOME或 Windows 下的%APPDATA%;设成%APPDATA%\Composer是无效的,得写全路径如C:\Users\Name\AppData\Roaming\Composer -
COMPOSER_HOME/bin必须加入PATH,否则全局安装的二进制命令找不到 - Linux/macOS 下检查是否用了
sudo composer导致权限错乱:root 用户的COMPOSER_HOME和当前用户不一致,全局 bin 目录可能写在 root 家目录下
最易被忽略的点是:你以为在改配置,其实是在破坏收敛性。所有方案最终必须产出一个合法、语义正确的 composer.json,而不是靠“合并”来掩盖设计缺陷。

















