composer仅识别文档列出的环境变量名,如composer_no_scripts;自定义变量如app_env、my_custom_flag被忽略,不解析、不报错、不透传;${var}插值仅在config.http-basic等少数字段生效,且仅启动时解析;scripts中需用env键显式传参,否则子进程无法获取;composer_home覆盖后须手动迁移配置与权限。

Composer只认自己文档里列出来的环境变量名
不是所有VAR=value composer install都能起作用。Composer 启动时会检查特定前缀和名称的环境变量,比如COMPOSER_NO_SCRIPTS、COMPOSER_MEMORY_LIMIT、HTTP_PROXY,但MY_CUSTOM_FLAG=1这种自定义名完全被忽略——它不解析、不报错、也不透传给子进程。
常见误用场景:
- 在 CI 脚本里写
APP_ENV=prod composer install,指望 Composer 自己根据这个值切换行为 → 实际上它根本不读APP_ENV,只是把这个变量传给了后续 scripts(如post-install-cmd) - 设置
COMPOSER_AUTH='{"example.com":{...}}'后仍提示认证失败 →COMPOSER_AUTH不是官方支持变量,正确方式是用config.http-basic配合${GIT_TOKEN}插值
composer.json 里哪些字段真支持 ${VAR} 插值
${VAR} 只在少数明确标注“支持运行时变量”的配置项中生效,且解析时机是 Composer 启动初期(调用getenv()那一刻),不是执行 scripts 时。
支持插值的字段包括:
-
config.http-basic:例如{"private.example.com": {"username": "${GIT_USERNAME}", "password": "${GIT_TOKEN}"}} -
repositories[].url:可写成"${PRIVATE_REPO_URL}",用于私有 Packagist 地址 -
config.process-timeout、config.notify-batch等数值型配置,但变量值必须是纯数字字符串(如"${COMPOSER_TIMEOUT}"对应300)
不支持插值的字段(写了也白写):
-
config.repos、config.github-protocols—— 官方文档没写支持,实际无效 -
scripts里的命令字符串本身,比如"post-install-cmd": "APP_ENV=${APP_ENV} php artisan config:clear"是错的;应由外部传入APP_ENV,脚本内直接用
env 键才是脚本里读取变量的唯一可靠方式
你在终端执行APP_ENV=prod composer run test,脚本里却读不到$_ENV['APP_ENV']?这不是 bug,是设计如此。Composer 默认不把父 shell 的环境变量透传给子进程,尤其在 Windows 或某些 CI 环境下更明显。
正确做法是在composer.json的 script 定义里显式声明env键:
{
"scripts": {
"test-with-env": {
"script": "php test.php",
"env": {
"APP_ENV": "testing",
"DB_HOST": "localhost"
}
}
}
}
这样test.php里才能稳定拿到$_SERVER['APP_ENV'](注意:$_ENV可能为空,$_SERVER才可靠)。
动态传参限制:
-
--env参数只影响 Composer 自身行为(如切源),不自动注入 scripts 子进程 - shell 前置赋值(
APP_ENV=prod composer run ...)在 Linux/macOS 有效,Windows CMD 下必须用set APP_ENV=prod && composer run ... -
env键不支持 shell 展开,"PORT": "$PORT"会原样传入,不会替换
COMPOSER_HOME 覆盖路径后必须手动迁移旧数据
COMPOSER_HOME不是“可选配置”,而是 Composer 查找全局配置的唯一路径来源。设了就硬用,不设才 fallback 到默认位置(~/.composer或%APPDATA%\Composer)。
但它的坑在于:设完不迁移,就等于“失联”。
- 必须手动创建目标目录:
mkdir -p $COMPOSER_HOME(Windows:mkdir D:\my-composer) - 必须手动拷 auth.json、config.json,且注意权限(Linux/macOS 上
auth.json需为600) - 全局安装的包(如
phpunit)不会自动重装,得跑一次composer global install - 路径不能含
~或$HOME,Windows 下也不能用%USERPROFILE%,否则静默失败
验证是否生效,别看终端提示,直接运行composer config --global home,输出必须是你设的绝对路径。











