Laravel 项目启动时只认根目录下的 .env 文件,命名必须为 .env 且不可更改;env() 仅在启动初期有效,配置缓存后须用 config() 读取,修改 .env 后需执行 config:clear 和 config:cache。

环境变量文件该放哪、怎么命名
Laravel 项目启动时只认 .env 文件,且必须放在项目根目录(即包含 artisan 的那一层),不能放在 config/ 或 storage/ 下,也不能叫 .env.production 或 .env.local —— 这些名字 Laravel 完全不读。
常见错误现象:AppServiceProvider 里 env('APP_DEBUG') 返回 null,或部署后数据库连不上,大概率是 .env 文件缺失或位置不对。
-
.env必须存在,且权限不能太开放(如避免 777,644 足够) - Git 默认会忽略
.env,所以部署时要手动上传或用 CI/CD 注入,别指望它自动同步 - 如果用 Docker,需通过
volumes挂载或env_file加载,不能只靠 COPY
env() 和 config() 函数的区别和调用时机
在 Laravel 中,env() 只在应用启动初期(bootstrap/app.php 和配置加载阶段)有效;一旦配置被缓存(比如运行过 php artisan config:cache),后续所有 env() 调用都返回 null 或默认值。
真正该用的地方只有两个:一是 .env 解析阶段(框架内部),二是本地开发调试临时看值。生产环境务必改用 config()。
- 错误写法:
if (env('ENABLE_FEATURE_X')) { ... }—— 缓存后永远不执行 - 正确写法:先在
config/app.php里定义'enable_feature_x' => env('ENABLE_FEATURE_X', false),再用config('app.enable_feature_x') - 运行
php artisan config:clear不会恢复env()的可用性,它只清缓存,不重启环境加载流程
部署时如何安全注入环境变量
服务器环境(如 Nginx + PHP-FPM)不继承 shell 的 export 变量,直接在终端设 export APP_KEY=xxx 对 Web 请求完全无效。必须让 PHP 进程在启动时就能读到。
最稳妥的方式是把变量写进 PHP-FPM 的 pool 配置,而不是依赖 .env 或 Apache 的 SetEnv(容易漏配或被覆盖)。
- 编辑
/etc/php/{version}/fpm/pool.d/www.conf,加一行:env[APP_KEY] = base64:...(注意:值里有空格或特殊字符必须 base64 编码) - 避免在
nginx.conf里用fastcgi_param传敏感变量,它可能被日志记录或意外暴露 - Docker 用户优先用
environment:+env_file:组合,并确保.env不进镜像(.dockerignore 里加上)
config:cache 后修改 .env 为什么没反应
因为 php artisan config:cache 会把所有 config/*.php 文件里用到的 env() 结果“快照”成一个 PHP 数组文件(bootstrap/cache/config.php),之后 Laravel 完全绕过 .env 和 env() 函数。
这个机制提升性能,但也意味着:改了 .env 但忘了重跑 config:cache,等于白改。
- 上线前必做:改完
.env→php artisan config:clear→php artisan config:cache - CI/CD 流水线里,
config:cache应该在最后一步执行,且确保它读的是目标环境的.env - 有些托管平台(如 Forge、Envoyer)会自动处理,但自建服务器必须自己盯住这三步顺序
环境变量不是“写进去就生效”的开关,它是 Laravel 启动生命周期里的一个短暂窗口——错过那个时机,后面所有操作都在旧快照上运行。最常被忽略的是缓存与重载之间的断层,尤其在热更新配置时。


















