执行 php artisan config:cache 后 env() 失效,因框架启动时跳过 .env 加载,仅从 bootstrap/cache/config.php 读取配置;此时必须用 config() 读取,且修改 .env 后需重新运行 config:cache 才生效。

缓存后读取错乱,根本原因是 config() 读的是缓存文件,而 env() 在缓存启用后已失效 —— 但很多人还在代码里混用,或者改了 .env 却没重刷缓存。
为什么 env() 突然不生效了
执行过 php artisan config:cache 后,Laravel 启动时不再加载 .env,而是直接 require bootstrap/cache/config.php。此时调用 env('DB_HOST') 会返回 null(或默认值),因为 getenv() 已被绕过。
-
env()只在配置未缓存时可靠;缓存后它无法反映.env的最新值 -
config('database.host')才是唯一安全的读取方式,它从缓存数组中取值 - 如果非要用
env()(比如在config/database.php中动态拼接 DSN),必须确保该配置项不参与缓存 —— 但 Laravel 5.8+ 会直接报错Your configuration files are not serializable
本地开发时数据库连接“串库”
多项目共用 Apache 或 PHP-FPM 进程时,putenv() 和 getenv() 是进程级、非线程安全的。一个项目改了环境变量,可能污染另一个项目的 env() 调用结果,导致 config:cache 生成的缓存文件写入了错误的 DB 配置。
- 典型现象:访问
test.me时却连上了api-test.me的数据库 - PHP 线程安全(TS)模式下尤其明显,NTS 版本更稳定
- 临时规避:在
config/database.php中放弃env(),直接写死'host' => '127.0.0.1'等值 - 长期方案:用
prefork模式运行 Apache,或改用 Swoole/PHP内置服务器做本地开发
修改 .env 后页面没变化
这是最常被忽略的操作断点:缓存存在 → 你改了 .env → 但 config.php 还是旧的 → 应用照旧读旧配置。
- 必须执行
php artisan config:clear && php artisan config:cache才能生效 -
config:clear只删bootstrap/cache/config.php,不碰其他缓存(如路由、视图) - CI/CD 部署脚本里漏掉这步,会导致线上配置永远滞后于
.env - 开发环境建议禁用
config:cache,只在生产环境启用
真正容易被忽略的点是:缓存不是“开关”,而是一次性快照。它把所有 config/*.php 文件的返回值序列化进一个 PHP 数组文件 —— 一旦生成,就和 .env、getenv()、甚至部分运行时逻辑彻底脱钩。











