composer.json 的 config 项完全覆盖全局配置,非合并;bin-dir 必须位于 vendor-dir 内或满足绝对路径校验,否则静默回退;config 不支持嵌套合并,缓存可能导致修改不生效。

composer.json 里的 config 项优先级高于全局 config.json
项目根目录下的 composer.json 中的 "config" 字段,会完全覆盖全局配置(COMPOSER_HOME/config.json 或 ~/.composer/config.json)中同名键。这不是“合并”,而是“覆盖”——比如项目里设了 "bin-dir": "bin",哪怕全局写了 "bin-dir": "vendor/bin",执行 composer install 时最终生效的仍是 bin。
常见错误现象:composer dump-autoload 后发现 vendor/bin 下没生成脚本,但本地确认包含 bin 声明——大概率是项目 composer.json 里误配了 "bin-dir",或压根没配而依赖了被覆盖的全局值。
- 全局 config 仅影响未在项目中声明的 config 键
-
composer.json中的config不支持嵌套合并,例如"github-protocols"是完整替换数组,不是追加 - 运行
composer config --list --global和composer config --list可分别查看全局和当前项目的实际生效配置
如何临时绕过项目 config 使用全局设置
某些 CI 场景需要强制使用全局 bin-dir 或 process-timeout,又不能改项目 composer.json。可用 -n(no-interaction)配合 --no-plugins + 环境变量重置:
COMPOSER_HOME=/tmp/composer-global composer install --no-plugins
更稳妥的做法是用 COMPOSER 环境变量临时指定一个空/精简的配置文件:
COMPOSER=/dev/null composer install
注意:/dev/null 会让 Composer 完全忽略项目 composer.json 的 config,但也会跳过 autoload、scripts 等——仅适合调试 config 本身。真要保留项目逻辑只换 config,应新建一个最小 composer.json 文件,只保留 {"config": {...}} 段落,再用 COMPOSER=path/to/minimal.json composer install。
- 直接删项目
composer.json的config段不是好办法:Git 提交记录和协作成员会受影响 -
composer config --global修改的是全局,对已有项目无回溯效果;修改后需重新运行composer install或update才会应用新 config - 插件(如
hirak/prestissimo)可能自行读取 config,它们的优先级独立于 Composer 核心,不受上述规则约束
vendor-dir 和 bin-dir 路径冲突的实际表现
当 vendor-dir 设为相对路径(如 "vendor"),而 bin-dir 设为绝对路径(如 "/usr/local/bin"),Composer 会静默忽略 bin-dir 设置,并退回到默认的 vendor/bin。这不是报错,而是内部校验失败后的 fallback。
原因在于:Composer 要求 bin-dir 必须位于 vendor-dir 内部或其子目录(除非 vendor-dir 是绝对路径且 bin-dir 显式声明为绝对路径并满足权限检查)。否则,composer install 会输出类似提示:
Warning: The bin-dir is not relative to the vendor-dir, skipping binary installation.
- 推荐写法:
"vendor-dir": "vendor"+"bin-dir": "vendor/bin"(默认值,可省略) - 若必须外挂 bin 目录,先确保
vendor-dir是绝对路径,例如"vendor-dir": "/var/www/myapp/vendor",再设"bin-dir": "/usr/local/bin" - Windows 下路径分隔符不敏感,但反斜杠需转义或用正斜杠;混用会导致
bin脚本生成失败且无明确错误
config 的加载顺序与缓存干扰
Composer 会缓存 composer.json 解析结果(包括 config),尤其在使用 composer install --prefer-dist 后。如果改了 config 却没看到效果,不是优先级问题,很可能是缓存没清。
验证方式:运行 composer show -s(显示当前配置摘要),对比是否与预期一致。若不一致,先执行:
composer clear-cache
然后再 composer install。注意:clear-cache 不清除已安装的 vendor,只清下载包缓存和配置解析缓存。
- 某些 IDE(如 PHPStorm)会缓存 Composer 配置用于代码补全,改完
composer.json后需手动触发 “Reload project” - 在 Docker 中运行时,
COMPOSER_HOME若挂载到宿主机,全局 config 可能被容器间共享,导致行为不一致 -
config中的布尔值(如"preferred-install")必须写字符串"source"或"dist",写true/false会被忽略且不报错
github-protocols 或 fxp-asset 相关配置被整个顶掉;还有就是 bin-dir 路径看似合法,实则因 vendor-dir 相对性触发静默 fallback —— 这两种情况都不会报错,只能靠 composer show -s 和日志里的 warning 来定位。










