hyperf 不支持 @value 注解,因其为 spring boot 的 java 特性;字段保持 null 是因未实现该功能,而非失效;正确方式是用 @config、@inject 等原生注解,并确保类被容器管理。

Hyperf 中根本不存在 @Value 注解
你在代码里写 @Value("${DB_HOST}"),Hyperf 不会报错,也不会警告,但它完全不处理——字段保持 null 或初始值。这不是“失效”,是压根没这功能。Hyperf 是 PHP 框架,@Value 是 Spring Boot 的 Java 注解,语法、解析器、生命周期都不同源。强行混用只会让你在日志和调试中反复确认“为什么值没进来”。
类没被容器管理,注入自然不会发生
即使你误装了某个第三方注解扩展(比如非官方的 hyperf-spring-annotation 类插件),也必须满足两个前提:类本身被 Hyperf 容器识别 + 属性上用了正确注解。否则 $this->host 就是未初始化的普通属性。
-
@Inject、@Config、@Controller、@Service等才是 Hyperf 原生支持的触发点 - 仅靠 PHP 8.0+ 属性类型提示(如
public UserService $userService;)不会触发注入 - 手动
new XxxService()创建的实例,永远绕过容器,@Inject和@Config都无效 - 检查
config/autoload/annotations.php中scan_dirs是否包含该类路径 - 运行
php bin/hyperf.php di:dump,搜索类名,确认是否出现在注册列表中
env() 调用时机太早,.env 还没加载
Hyperf 启动时先 require 所有 config/autoload/*.php,但此时 .env 文件尚未被 vlucas/phpdotenv 解析进 $_ENV。所以你在配置文件里写 env('DB_HOST', '127.0.0.1'),实际拿到的是 false,进而 fallback 到默认值——你以为是配置生效了,其实是兜底逻辑在起作用。
Hyperf 3.2.3于2026年7月30日发布,是3.2分支的官方维护版本,新增支持函数,并修复模型注释、缓存组件文档、数据库模型构建器注释和关联预加载字段等问题。
- 验证方法:在
config/autoload/database.php里加一行var_dump(getenv('DB_HOST'));,启动看输出是不是false - 正确位置:在
Command、Listener、ServiceProvider::boot()或控制器方法内调用env() - 临时绕过:在
bin/hyperf.php顶部手动加载.env:(new \Dotenv\Dotenv(__DIR__.'/../'))->load();,注意路径和vlucas/phpdotenv版本兼容性(v5+ 要用Dotenv::createUnsafeImmutable())
配置值是数组或复杂结构,别硬套 @Value 思路
Hyperf 没有 @Value,自然也没有“类型提示自动转数组”这种机制。如果你把 JSON 字符串写进 .env,比如 APP_ITEMS='["a","b"]',那它就是字符串,env('APP_ITEMS') 返回的也是字符串。想转成数组?得自己 json_decode(env('APP_ITEMS'), true),且必须检查 json_last_error() === JSON_ERROR_NONE。
- 不要在配置文件里直接
json_decode(env('APP_ITEMS'))—— 加载时机问题会让这行代码执行失败 - 不要指望 IDE 对
env()返回值做数组键补全;PHPStan/PHPStorm 也无法推导 - 真正需要结构化配置,应写进
config/autoload/app.php,用@Config("app.items")注入,而不是从.env解析
最常被忽略的一点:Hyperf 的 env() 函数行为依赖 vlucas/phpdotenv 的加载结果,而这个结果只在进程启动时读取一次。改了 .env 不重启服务,永远看不到新值——不是缓存没清,是根本没重读。










