composer 2.2+ 不支持全局插件白名单,composer config --global allow-plugins 配置无效,仅读取项目级 composer.json 中顶层或 config 节点下的 allow-plugins(对象或数组格式),且必须与插件包 name 字段完全一致。

global config 不能配置插件白名单
Composer 没有全局插件白名单机制。你在 composer config --global allow-plugins 里写的任何值,都不会生效——Composer 2.2+ 明确只读取项目根目录 composer.json 中的 config.allow-plugins 字段,全局配置会被完全忽略。
常见误操作是执行:composer config --global allow-plugins '{"phpstan/extension-installer": true}'
结果是:这个配置确实写进了 ~/.composer/config.json,但 composer install 运行时压根不看它,插件仍被拒绝加载,报错仍是 The plugin phpstan/extension-installer is not allowed to be loaded。
- 唯一有效的白名单位置:项目级
composer.json的顶层config下 - 全局配置中
allow-plugins字段存在,但 Composer 不解析它 - 验证方式:在任意项目中运行
composer config --list | grep allow-plugins,输出只来自项目composer.json,不会混入全局值
为什么不能全局统一管理插件白名单
这是 Composer 的安全设计决策:插件执行权限必须与依赖树绑定。同一个插件(如 phpstan/extension-installer)在 A 项目中可能是可信的,在 B 项目中却可能因依赖链被恶意包污染。强制项目级声明,能确保每个 composer.lock 文件都明确记录“该插件在此项目中被授权”。
- CI/CD 流水线失败?不是配置漏了,而是某个项目没加白名单
- 团队成员本地行为不一致?大概率有人手动改过全局
config.json,或用了--no-plugins参数绕过校验 - 想“一劳永逸”?只能靠脚本批量注入白名单到各项目
composer.json,不能靠全局开关
替代方案:用 --no-plugins 临时禁用所有插件
如果你真需要跨项目统一禁用插件(比如调试 autoload 失败、排查 CI 环境异常),--no-plugins 是唯一可靠方式。它不依赖任何配置,纯运行时跳过所有 PluginInterface::activate() 调用。
- 命令示例:
composer install --no-plugins --no-dev --prefer-dist - 效果:连
composer/installers这类官方插件也会被跳过,可能导致 vendor/autoload.php 生成失败或路径错乱 - 注意:它不修改任何文件,也不影响
composer.lock,下次不带该参数就恢复原状 - 别把它和白名单混淆:
--no-plugins是“全关”,allow-plugins是“只开指定几个”
最容易被忽略的细节
白名单键名必须与插件包的 name 字段**逐字符一致**,包括 vendor 名、斜杠、大小写。去插件自己的 composer.json 里抄,别从 require 或 GitHub URL 里猜。
- 错误写法:
"extension-installer"(漏phpstan/)、"PHPStan\ExtensionInstaller"(类名不是包名) - 正确写法:
"phpstan/extension-installer": true - 查真实名称最准的方式:
composer show --plugins(需先临时允许插件加载一次) - 生产部署时,建议显式写
"*": false防止未来新增插件意外放行











