nginx 传自定义变量给 php 需三步:fastcgi_param 必须放在 include fastcgi_params 之后;php 默认仅存入 $_server,thinkphp 需用 putenv 同步至环境变量;变量名须全大写、下划线分隔、无特殊字符。

直接在 Nginx 的 location ~ \.php$ 块里用 fastcgi_param 添加键值对,就能把自定义变量传进 PHP 进程。关键不是“加不加”,而是加在哪、怎么加、PHP 侧怎么接——三者缺一不可。
必须放在 include fastcgi_params 之后
很多人配置了却读不到,根本原因是位置错了。include fastcgi_params 会加载默认的一批 fastcgi_param 指令(比如 SCRIPT_FILENAME、REQUEST_METHOD),它内部已经设好了变量覆盖逻辑。如果你把自定义项写在 include 前面,就会被后面同名的默认项覆盖掉。
- ✅ 正确顺序:
include fastcgi_params;fastcgi_param APP_ENV "production";fastcgi_param DB_HOST "10.0.1.5";- ❌ 错误写法(会被覆盖):
fastcgi_param APP_ENV "production";include fastcgi_params;
变量默认只进 $_SERVER,ThinkPHP 需手动同步到 $_ENV
Nginx 透传的变量,PHP 默认只写入 $_SERVER 数组,不会自动填充 $_ENV 或触发 putenv()。而 ThinkPHP 的 Env::get('APP_ENV') 默认从 $_ENV 或系统环境读取,所以不额外处理就拿不到。
- 在入口文件
public/index.php开头加一段同步逻辑: foreach ($_SERVER as $key => $value) { if (strpos($key, 'HTTP_') !== 0 && !is_numeric($key[0])) { putenv("{$key}={$value}"); } }- 或更稳妥地只同步你明确声明的变量名:
putenv('APP_ENV=' . ($_SERVER['APP_ENV'] ?? 'dev'));- 这样
Env::get('APP_ENV')就能正常返回了
注意变量命名规范和大小写敏感
FastCGI 协议要求环境变量名全大写、下划线分隔,且不能含特殊字符。Nginx 不会校验,但 PHP 接收后可能无法识别。
- ✅ 推荐写法:
fastcgi_param RUNTIME_ENV "prod"; - ❌ 避免写法:
fastcgi_param runtime-env "prod";(含短横线)、fastcgi_param runtimeEnv "prod";(驼峰)、fastcgi_param env "prod";(太泛,易冲突) - 另外,Linux 环境下变量名严格区分大小写,
APP_ENV和app_env是两个不同变量
验证是否生效的简单方法
不用重启服务也能快速确认变量有没有传过去:
- 在 PHP 脚本里临时加一行:
var_dump($_SERVER['APP_ENV'] ?? 'not set'); - 或者执行
php -r "print_r(getenv('APP_ENV'));"(前提是已用putenv同步过) - 检查 Nginx 错误日志:
tail -f /var/log/nginx/error.log,语法错误会在这里报出 - 修改完配置别忘了重载:
nginx -t && nginx -s reload











