Composer仅识别COMPOSER_*开头的环境变量(如COMPOSER_HOME、COMPOSER_CACHE_DIR、COMPOSER_NO_INTERACTION、COMPOSER_PLATFORM_CHECK),用于控制自身行为(缓存路径、交互模式、平台校验等),不参与依赖解析,也不影响require/require-dev的安装结果;设COMPOSER_ENV=prod无效,跳过dev包须显式使用--no-dev参数。

Composer 不会读取 APP_ENV、NODE_ENV 这类项目级环境变量来决定装什么包——它只认 COMPOSER_* 开头的变量,且仅用于控制自身行为(如缓存路径、交互模式),不参与依赖解析逻辑。
COMPOSER_* 变量只影响 Composer 自身,不改变 require/require-dev 的安装结果
很多人误以为设个 COMPOSER_ENV=prod 就能让 Composer 自动跳过 require-dev,实际完全无效。Composer 官方只识别以下前缀的变量:
-
COMPOSER_HOME:全局配置和缓存根目录 -
COMPOSER_CACHE_DIR:单独指定缓存路径(覆盖COMPOSER_HOME/cache) -
COMPOSER_NO_INTERACTION:强制非交互模式,CI 必开 -
COMPOSER_PLATFORM_CHECK:控制是否校验本地 PHP 扩展是否匹配config.platform
这些变量不会让 composer install 突然“理解”你当前是生产环境并自动加 --no-dev——那得靠命令参数或 CI 脚本显式写死。
真正影响依赖安装的只有 --no-dev 和 COMPOSER_PLATFORM_CHECK=0
生产部署最常漏掉的两个关键点:
- 没加
--no-dev:导致phpunit、laravel-debugbar等被装进线上环境,体积膨胀、autoload 加载变慢、甚至因扩展缺失(如ext-xdebug)直接报错 - 本地有
xdebug,但线上没有,而某个require-dev包(如新版phpunit)声明了"ext-xdebug": "*"—— 此时composer install --no-dev仍会失败,因为平台检查默认开启
解决方案分两步:
- 加
--no-dev跳过 dev 包安装 - 加
--ignore-platform-reqs或设COMPOSER_PLATFORM_CHECK=0关闭扩展校验(推荐后者,更明确)
最终线上命令应为:COMPOSER_PLATFORM_CHECK=0 composer install --no-dev --optimize-autoloader --no-interaction
config.platform 是唯一能“模拟不同服务器环境”的配置项
当你的开发机是 PHP 8.3,但线上是 PHP 8.1,且某包在 8.3 下才支持最新版(比如 symfony/console v7),直接 composer update 可能锁出不兼容版本。这时必须用 config.platform 告诉 Composer:“请按 PHP 8.1 环境选包”:
"config": {
"platform": {
"php": "8.1.28",
"ext-mbstring": "8.1.28",
"ext-pdo_mysql": "8.1.28"
}
}
注意:
- 版本号必须写死,不能用
^8.1或~8.1,否则无效 -
ext-pdo_mysql这类关键扩展容易漏写,线上报Class 'PDO' not found往往就是它没声明 -
config.platform对require-dev同样生效——如果你本地开发依赖高版本phpunit,但platform.php锁太死,可能降级到不兼容旧版
Docker 和 CI 中 COMPOSER_HOME 配置容易失效
在 Docker 构建阶段设 ENV COMPOSER_HOME /tmp/composer,看似合理,但常因执行顺序出问题:
- 如果
composer install在ENV指令之后才运行,且容器里用了sudo或非 root 用户,子进程可能拿不到该变量 - CI runner(如 GitHub Actions)中,
COMPOSER_HOME需在每个 step 显式传入,不能只靠 job-level env
验证是否生效的唯一方式是运行:composer config --list --global,看 “Global configuration file” 路径是否为你预期的绝对路径。若看到 ~/.composer,说明变量根本没传进去。
复杂点在于:platform 配置、--no-dev、COMPOSER_PLATFORM_CHECK 三者要协同生效,缺一不可;而它们各自的作用域和生效时机完全不同——platform 影响 update 时的版本解析,--no-dev 控制 install 时的包下载,COMPOSER_PLATFORM_CHECK 则决定安装前是否校验扩展。稍有错配,就可能出现本地能装、CI 过不了、线上启动报错的断裂链路。











