env() 返回 false 或默认值,根本原因通常是 putenv() 被禁用、docker 启动未传环境变量或 php variables_order 不含 e;需分别验证函数可用性、容器 -e 参数及 variables_order 配置。

Hyperf 项目里 env() 返回 false 或默认值,大概率不是 .env 文件写错了,而是 putenv() 被禁用,或 Docker 容器启动时根本没把环境变量传进去——这两类问题现象相似,但根因和修复路径完全不同。
putenv() 被禁用导致 dotenv 加载失败
Hyperf 默认依赖 vlucas/phpdotenv 解析 .env 并调用 putenv() 注入运行时环境。一旦该函数被禁用,getenv() 和 env() 就永远拿不到值。
- 执行
php -r "var_dump(function_exists('putenv'));",输出bool(false)即确认被禁用 - 检查
php -i | grep disable_functions,看输出里是否含putenv - 禁用场景常见于共享主机、云函数(如阿里云 FC)、安全加固的 Docker 基础镜像(如
php:alpine某些精简版) - 临时验证:在
bin/hyperf.php顶部加(new \Dotenv\Dotenv(BASE_PATH))->load();(需确保已安装对应版本的 phpdotenv) - 生产环境不建议启用
putenv(),应改用 Web 服务器(Nginx)或 PHP-FPM 直接注入环境变量
Docker 启动时未传递环境变量
容器内 getenv('APP_ENV') 返回 false,但宿主机 echo $APP_ENV 有值,说明变量根本没进容器。
- 启动命令必须显式用
-e传参:docker run -e APP_ENV=prod -e DB_HOST=10.0.1.5 ... - 不要依赖
.env文件自动加载——Docker 容器默认不挂载它,且putenv()禁用时也无效 - 使用
docker-compose.yml时,确保environment:下是键值对,不是env_file:(后者只在 docker-compose build 阶段读取,不进运行时) - 进容器验证:
docker exec -it your-container php -r "var_dump(getenv('APP_ENV'));",若为false,说明变量没传进去 -
docker inspect查看Config.Env字段,确认变量是否出现在列表中
PHP variables_order 不含 E 导致 $_ENV 失效
即使 putenv() 正常、变量也传进了容器,$_ENV['DB_HOST'] 仍可能为 null,而 getenv('DB_HOST') 有值——这是 PHP 自身配置问题。
- 执行
php -i | grep variables_order,典型安全配置是GPCS(不含E),此时$_ENV不会被填充 -
env()函数底层优先查$_ENV,再 fallback 到getenv();若$_ENV为空且getenv()又因putenv()禁用失败,就彻底拿不到 - 不建议修改
variables_order,应统一用getenv()替代$_ENV或env() - Hyperf 的
env()是封装函数,源码里明确写了先读$_ENV,所以它比getenv()更容易踩这个坑
真正要盯住的只有三件事:putenv 是否可用、容器启动是否带 -e、PHP 的 variables_order 是否允许读 $_ENV。其他所有“.env 没生效”的表象,基本都落在这三个点上。











