getenv() 读取环境变量最可靠,不依赖 variables_order 配置,可跨 Web 和 CLI 稳定工作;$_ENV 需 variables_order 包含 E 才有效;$_SERVER 混杂其他参数易误读;putenv() 仅当前进程有效;.env 仅限开发,生产应由 Web 服务器或 PHP-FPM 注入。

getenv() 读取环境变量最可靠,但得确认 variables_order 配置
PHP里读环境变量,getenv() 是首选,它不依赖 php.ini 的 variables_order 设置,能跨 Web 和 CLI 环境稳定工作。但如果你习惯用 $_ENV,就得检查 php.ini 里 variables_order 是否包含 E(比如默认值是 "GPCS",没 E 就不会填充 $_ENV)。$_SERVER 虽然通常有环境变量,但它混着 Web 服务器传来的其他参数,容易误读。
常见错误现象:
-
$_ENV['DB_HOST']返回null,但getenv('DB_HOST')有值 →variables_order缺E - CLI 下能读到变量,Web 请求里读不到 → Web 服务器(如 Nginx)没把变量透传给 PHP
putenv() 只在当前请求有效,别指望它跨请求或持久化
putenv("APP_ENV=production") 确实能设变量,但它只影响当前 PHP 进程的生命周期,请求结束就丢。它不会写入系统环境,也不会被子进程继承(除非你显式调用 proc_open() 并配置了环境)。所以它不适合做“全局配置开关”,更适合临时覆盖,比如单元测试中模拟不同环境。
使用场景:
立即学习“PHP免费学习笔记(深入)”;
- 在 PHPUnit 测试前强制设置
APP_ENV=test - CLI 脚本中根据参数动态调整日志级别:
putenv("LOG_LEVEL=debug")
容易踩的坑:
- 在 Laravel 中用
putenv()修改APP_KEY后没清缓存 → 配置仍走旧值(因为config:cache已固化) - 在 Apache 的
.htaccess里用SetEnv,却在脚本里用putenv()覆盖 → 实际生效的是后者,但可能和框架预期冲突
dotenv 库加载 .env 文件,开发阶段最常用,但生产环境要禁用
vlucas/phpdotenv 是开发期事实标准:自动把 .env 文件内容注入到环境变量,之后 getenv() 就能直接用。但它不是生产环境该出现的东西——.env 文件不该上传到服务器,更不该被 Web 可访问。
实操建议:
- 入口文件(如
index.php或bootstrap/app.php)开头加载:$dotenv = Dotenv\Dotenv::createImmutable(__DIR__); $dotenv->load(); - 用
.gitignore明确排除.env,避免密钥泄露 - 生产部署时,删掉
dotenv加载逻辑,或通过if (getenv('APP_ENV') !== 'production')包裹
注意点:
-
.env里含空格或特殊字符(如API_KEY="abc def")必须加引号,否则解析失败 - 不要在
.env里写export KEY=value—— dotenv 不识别 shell 语法
Web 服务器层传环境变量才是生产环境正解
Apache 用 SetEnv,Nginx 用 fastcgi_param,PHP-FPM 池里用 env[KEY] = value —— 这些方式才真正把变量注入到 PHP 进程启动环境,getenv() 和 $_ENV 都能稳定读取,且不受脚本内 putenv() 干扰。
Nginx 示例(server 块内):
fastcgi_param APP_ENV "production"; fastcgi_param DB_HOST "10.0.1.5"; fastcgi_param DB_PASSWORD "xxx";
Apache 示例(虚拟主机或 .htaccess):
<IfModule mod_env.c>
SetEnv APP_ENV production
SetEnv DB_HOST 10.0.1.5
</IfModule>
关键细节:
- PHP-FPM 配置中若设了
clear_env = yes(默认值),会清空所有父进程环境变量,必须显式用env[KEY]重设 - Docker 环境下,优先用
docker-compose.yml的environment:或env_file:,再由容器运行时注入到 PHP 进程 - 敏感值(如密码)绝不能出现在 Web 服务器配置明文里,应结合 secrets(Docker Swarm/K8s)或外部密钥管理服务
真正容易被忽略的是变量作用域的叠加顺序:Web 服务器传入的变量 > putenv() 设置的变量 > .env 加载的变量。一旦线上出问题,先看 phpinfo() 里 Environment 和 $_SERVER 区块,比翻代码快得多。



















