Hyperf 3.1 中修改 .env 数据库配置不生效,主因是 .env 仅启动时加载一次、未重启服务,或配置被硬编码覆盖、watcher 未监听 .env、连接池复用旧连接所致。

Hyperf 3.1 中修改 .env 的数据库配置(如 DB_HOST、DB_DATABASE)后不生效,通常不是改错了,而是框架没重新加载新值——关键在环境变量加载机制和运行时缓存环节出了问题。
确认 .env 是否被正确加载
Hyperf 默认使用 vlucas/phpdotenv 加载 .env,但只在应用启动初期读取一次。若你改了 .env 后没重启服务,旧值仍在内存中。
- 检查是否在
bin/hyperf.php或config/autoload/processes.php中误用了Dotenv::createMutable()或路径错误(例如__DIR__指向了子目录),导致没找到.env - 运行
php bin/hyperf.php di:info或临时加一行日志:var_dump($_ENV['DB_HOST'] ?? 'not set');,验证环境变量是否已注入 - 确保
.env文件位于项目根目录(与composer.json同级),且权限为644,CLI 用户可读
检查配置是否被覆盖或缓存
Hyperf 不像 Laravel 那样有 config:cache,但它会把 .env 解析后的值合并进 config/autoload/database.php 等配置文件中。如果这些配置文件里硬编码了 DB 参数,就会覆盖 .env 值。
- 打开
config/autoload/database.php,确认'host' => env('DB_HOST', '127.0.0.1')这类写法,而不是直接写死'host' => '192.168.1.100' - 检查是否有其他配置文件(如
config/autoload/params.php)或中间件提前调用了DatabaseFactory,导致连接池初始化过早 - 运行
php bin/hyperf.php config:show database查看最终生效的数据库配置,确认输出值是否为你刚改的
热更新未触发配置重载
用 server:watch 启动时,改 .env 不会自动重启进程,因为 .env 不在默认监听路径内(watcher 默认只监控 app/ 和 config/)。
- 编辑
config/autoload/watcher.php,在'watch.dir'数组中添加BASE_PATH . '/.env' - 保存后必须手动重启
server:watch(Ctrl+C 再执行),否则改动不会触发 reload - 更稳妥的做法:开发中直接用
server:start启动,改完.env后执行kill -USR1 $(cat runtime/hyperf.pid)触发平滑重载
检查数据库连接池是否复用旧连接
即使配置更新了,已建立的连接池(如 PDO 或 Redis 连接)仍维持旧连接,新请求才走新配置。这会导致“看似没生效”的错觉。
- 执行
php bin/hyperf.php server:stop彻底关闭服务,再server:start或server:watch - 如果用了 Swoole 连接池,确认
config/autoload/databases.php中的'max_idle_time'设置合理(如60秒),避免长期空闲连接残留 - 在控制器中加一句
var_dump(\Hyperf\Database\Connection::getPdo()->getAttribute(\PDO::ATTR_CONNECTION_STATUS));,观察连接是否指向新地址


















