Composer 不支持白名单灰度配置,灰度必须在 PHP 运行时通过条件判断实现;多环境依赖需用多份 composer.json 配合 COMPOSER 环境变量指定,且须确保 autoload 兼容与副作用隔离。

Composer 本身不支持白名单灰度配置
Composer 是 PHP 的依赖管理工具,它只负责下载、安装、更新和自动加载包,composer.json 里没有「灰度」或「白名单」这类运行时控制机制。所谓“给白名单做灰度配置”,实际是业务逻辑层要做的事,不是 Composer 能解决的——你不能靠 require 或 config 字段动态开关某个包的功能。
灰度通常发生在运行时,不是安装时
如果你的目标是让部分用户(比如内测账号、特定 IP、灰度环境变量)启用新功能(比如一个刚引入的包 acme/feature-flag),那必须在代码中判断条件,再决定是否调用该包的类或方法:
- 不要在
composer.json中 conditional require(Composer 不支持) - 不要试图用
autoload-dev或scripts模拟灰度(它们只影响开发/构建阶段) - 真正生效的灰度逻辑必须写在 PHP 运行时,例如在控制器、中间件或服务启动处
示例:你在 composer.json 中已安装了 acme/feature-flag,但只对 $_SERVER['HTTP_X_GRAYSCALE'] === '1' 的请求才启用:
// 某个服务入口
if (isset($_SERVER['HTTP_X_GRAYSCALE']) && $_SERVER['HTTP_X_GRAYSCALE'] === '1') {
$flagService = new \Acme\FeatureFlag\FlagService();
$flagService->enable('new_checkout_flow');
}
想实现“按环境加载不同依赖”?用 Composer 的 platform 和 config.platform 不行,但可以用 replace + 多套 composer.json
极少数场景下,你确实需要不同环境装不同版本的包(比如灰度环境用 vendor/package:dev-feature-branch,正式环境用 vendor/package:^2.0)。这时不能靠单个 composer.json 动态切换,而应:
- 维护多份
composer.json文件(如composer.gray.json、composer.prod.json) - 通过
COMPOSER=composer.gray.json composer install指定使用哪一份 - 用
replace阻止冲突(例如灰度版替换了正式版的同名包) - 注意:所有变体仍需保证
autoload兼容,否则类找不到
最容易被忽略的一点:autoload 不会因灰度条件跳过
只要包进了 vendor/,它的类就可能被自动加载器加载——哪怕你从不显式 use 它。如果灰度包有副作用(比如构造函数发 HTTP 请求、改全局状态),仅靠运行时 if 判断不够。必须确保:
- 灰度包自身不执行初始化逻辑(推荐用延迟实例化)
- 关键类加命名空间隔离(避免非灰度环境意外触发 autoload)
- CI/CD 构建时检查
vendor/是否混入了不该上线的包(比如用composer show校验)
灰度不是配置问题,是架构问题。Composer 只管“有没有”,不管“用不用”。


















