hyperf的.env修改后不生效,根本原因是配置合并机制中同名键在php/yaml文件中已定义,导致.env被静默忽略;需用config:show确认来源,删runtime/container并重启服务。

Hyperf 的 .env 文件修改后不生效,根本不是缓存没清干净
Hyperf 读取 .env 是在启动早期阶段完成的,但它的配置合并机制决定了:即使你改了 .env,只要同名配置在 config/autoload/ 下的 PHP 或 YAML 文件里也存在,.env 就会被静默忽略——因为环境变量优先级虽高,但仅对“未定义”的键生效。常见错误是数据库 host、redis port 这类值在 databases.php 或 redis.php 里硬编码写了死值,.env 改了也白改。
执行 php bin/hyperf.php config:clear 完全无效
Hyperf 没有 config:clear 这个 Artisan 命令。它不生成类似 Laravel 的 bootstrap/cache/config.php 单一缓存文件,而是把合并后的配置直接注入容器,运行时无“配置缓存文件”可删。所谓“清理 config 缓存”,其实是误用 Laravel 经验导致的无效操作。真正要动的是:
-
runtime/container/:注解扫描、AOP 代理、DI 元数据都存在这里,改了.env后若涉及路由、中间件、注入逻辑变化,必须删 -
runtime/cache/:部分组件(如 Config 组件启用缓存时)会存序列化配置,但默认不开启,除非你显式调用了ConfigInterface::setCache() - PHP OpCache:如果
config/autoload/*.php文件被修改过,OpCache 可能还在用旧字节码,需重启 PHP-FPM 或执行opcache_reset()
怎么确认 .env 真的被加载并生效了
别猜,直接看最终合并结果:
php bin/hyperf.php config:show --all
这条命令会输出所有已合并的配置键值对,并标注来源(env、php、yml)。重点检查你要改的 key(比如 DB_HOST)是否显示来源为 env,且值是你刚写进 .env 的内容。如果来源是 php,说明 config/autoload/databases.php 里重复定义了;如果压根没出现这个 key,说明 .env 格式有错(比如漏了等号、引号不闭合)或文件权限不可读。
修改 .env 后必须做的三件事
不是“清缓存”,而是确保整个加载链路重跑一次:
-
rm -rf runtime/container:强制让框架在下次启动时重新扫描注解、重建代理类和 DI 映射(哪怕只改了.env,只要该变量被用于注解参数如#[Server(port: env('PORT'))],就必须删) - 检查
config/autoload/*.php是否覆盖了你想从.env控制的配置项,删掉或改成env('KEY', 'default')调用 - 重启服务:
php bin/hyperf.php start(开发)或php bin/hyperf.php server:restart(生产),热重载(watch)不触发注解重扫描,不能替代重启
最常被忽略的一点:Hyperf 默认根据 APP_ENV 加载 config/autoload/{dev,prod}/ 子目录,如果你在 .env 里写了 APP_ENV=dev,但部署时实际运行在 prod 环境,那 .env 里的值可能根本没参与合并——先运行 php bin/hyperf.php env 确认当前环境再调试。











