hyperf 的 env() 函数不支持 spring 的 @value 注解,必须通过 .env 文件配合 env() 函数读取,且需确保加载时机正确(容器初始化后)、.env 路径权限合法、无语法错误,并重启进程生效。

Hyperf 的 env() 函数不走 Spring 那套,别混用 @Value
Hyperf 没有 @Value 注解——这是 Spring Boot 的东西。你在 Hyperf 项目里看到 @Value,基本是误用了 Spring 风格的写法,或者引入了混淆的第三方扩展包。Hyperf 原生靠的是 env() 函数 + 配置文件自动加载机制。强行套用 @Value 不仅不会生效,还会因类未被容器管理、时机错位等问题导致值始终为 null 或默认值。
自定义配置文件中 env() 返回默认值,八成是加载时机太早
Hyperf 在启动早期(比如 Di\ClassLoader 初始化阶段)就加载 config/autoload/*.php,但此时 .env 文件尚未被 Dotenv 解析进 $_ENV 和 getenv()。所以你在 config/autoload/custom.php 里直接写 env('DB_HOST'),大概率拿到的是 false,进而 fallback 到默认值。
- 验证方法:在配置文件里加一行
var_dump(getenv('DB_HOST'));,启动时看是否输出false - 正确做法:把
env()调用推迟到容器已初始化后,比如放在Command、Listener或服务提供者boot()中 - 临时绕过:手动提前加载
.env,例如在bin/hyperf.php顶部加(new \Dotenv\Dotenv(__DIR__.'/../'))->load();(注意路径和vlucas/phpdotenv版本兼容性)
.env 文件本身没被读取?检查三个硬性条件
不是所有 .env 都会被加载。Hyperf 默认只认项目根目录下的 .env,且依赖 hyperf/framework 提供的 DotenvLoader。常见失效点:
-
.env文件权限不对(如 Windows 下 Git Bash 创建的换行符为 CRLF,某些版本phpdotenv会解析失败) - 环境变量名含空格或特殊字符但没用引号包裹,例如
API_KEY=abc def→ 应写成API_KEY="abc def" - 使用了
export前缀(export DB_HOST=127.0.0.1),Hyperf 的env()不识别这种 shell 导出语法 - PHP 进程启用了
variables_order中不含E(即禁用了$_ENV),可通过php -i | grep variables_order确认
缓存导致改了 .env 没反应?清 config 缓存不等于清环境变量
Hyperf 的 php bin/hyperf.php gen:publish 或 cache:clear 只清配置数组缓存(config/autoload/*.php 的返回值),不影响 getenv() 的运行时状态。改完 .env 后:
- CLI 命令需重启进程(关掉
php bin/hyperf.php start再重起) - HTTP 服务同理,Swoole worker 进程不 reload
.env,必须kill -USR1或完整重启 - 如果用了
opcache.enable=1且未配置opcache.revalidate_freq=0,env()函数本身可能被 OPcache 缓存住旧逻辑(极少见,但发生过)
最稳妥的验证方式:在任意可执行上下文中(比如一个 Command)里打印 getenv('YOUR_KEY') 和 env('YOUR_KEY'),两者结果必须一致才算真正生效。











