Composer脚本需通过env键显式声明环境变量才能在子进程中读取,如"APP_ENV": "testing";动态传参应优先使用.env文件+脚本解析,而非依赖shell前置赋值或--env参数。

Composer 脚本里不能直接用 $_ENV 或 getenv() 读取 shell 环境变量,因为 Composer 启动的子进程默认不继承父 shell 的环境(尤其在 Windows 或某些 CI 环境下更明显)。
composer.json 中的脚本如何正确传入环境变量
必须显式通过 env 键声明要传递的变量,否则即使你在终端里 FOO=bar composer run test,脚本里也拿不到 FOO。
示例写法:
工作流任务拆解与模型编排技能。使用场景:(1) 收到复杂工作任务需要拆解为可执行步骤,(2) 需要为不同步骤选择最合适的模型,(3) 需要跟踪工作流进度和模型使用情况,(4) 长时间任务卡住需要问题诊断和解决方案。
{
"scripts": {
"test": "php test.php",
"test-with-env": {
"script": "php test.php",
"env": {
"APP_ENV": "testing",
"DB_HOST": "localhost"
}
}
}
}
-
env下的键值对会在执行脚本前注入到子进程环境,PHP 脚本中可用getenv('APP_ENV')或$_SERVER['APP_ENV']读取 - 只支持静态字符串,不支持 shell 变量展开(比如
"DB_PORT": "$PORT"会原样传入,不会替换) - 如果变量名含特殊字符(如点号
.),部分系统可能丢弃——建议用下划线命名
运行时动态传参:用 --env 参数或命令行变量
Composer 2.2+ 支持 --env 参数,但注意它只影响 composer 自身行为(如切换仓库源),**不自动透传给脚本进程**。真正能动态传参的方式只有两种:
- 在命令行中前置设置:
APP_ENV=prod composer run test—— 这依赖 shell 行为,在 Linux/macOS 有效,Windows CMD 无效(需用 PowerShell 的$env:APP_ENV="prod"; composer run test) - 改用
php -d variables_order=EGPCS ...强制 PHP 加载环境,但太重,不推荐 - 最稳妥的做法:把动态变量写进
.env文件,再让脚本自己加载(比如用vizionnaire/laravel-env或原生parse_ini_file())
PHP 脚本里读取环境变量的兼容写法
别只信 getenv(),它在 variables_order 配置不当时可能返回 false;$_ENV 默认是空的(除非 php.ini 开启了 register_env,而现代 PHP 默认关)。
- 推荐统一用
$_SERVER['VAR_NAME']—— Composer 注入的变量一定存在于$_SERVER - 若需 fallback 到 .env 文件,用
$_SERVER['VAR_NAME'] ?? $_ENV['VAR_NAME'] ?? 'default'不可靠,应单独解析文件 - 敏感变量(如 API_KEY)不要硬编码在
composer.json里,哪怕只是测试值——容易误提交
真正麻烦的是跨平台一致性:Windows、Git Bash、Docker、CI runner 对环境变量的处理逻辑各不相同,与其反复调试,不如把关键配置抽成独立 JSON/INI 文件,由脚本主动加载。Composer 的 env 字段只是个快捷入口,不是环境管理方案。

















