不能直接提交 .env 到 Git,因其含数据库密码、API 密钥等敏感信息;生产环境应通过系统级环境变量(如 Nginx、PHP-FPM 或 Docker)注入,并在 config 中用 env() 函数安全引用,配置缓存后 .env 修改无效。

为什么 .env 文件在生产环境不能直接提交到 Git?
因为 .env 里通常包含数据库密码、API 密钥、JWT 密钥等敏感信息,一旦泄露,相当于交出服务器钥匙。Laravel 默认把 .env 加入 .gitignore,就是强制你别传——但这也带来新问题:部署时怎么让线上环境读到这些变量?
生产环境如何安全加载 .env 变量而不写死在代码里?
Laravel 启动时靠 Illuminate\Foundation\Bootstrap\LoadEnvironmentVariables 类加载 .env,但它只在 APP_ENV 为 local 时默认启用。生产环境(APP_ENV=production)下,它仍会尝试加载,但前提是文件存在且可读。关键点在于:不要依赖自动加载,而是用系统级环境变量兜底。
- 在 Web 服务器(Nginx/Apache)或 PHP-FPM 配置中,用
env[DB_PASSWORD]="xxx"或SetEnv DB_PASSWORD "xxx"显式注入变量 - 使用容器时(如 Docker),通过
-e DB_PASSWORD=xxx或environment:块注入 - 确保 PHP 的
$_ENV和getenv()能读取到这些值(某些 CGI 模式需开启variables_order = "EGPCS") - 验证方式:
php -r "echo getenv('DB_PASSWORD') ?: 'not set';"
config/database.php 里怎么安全引用 .env 变量?
所有 config/*.php 文件都是运行时执行的 PHP 脚本,所以可以直接调用 env() 函数。但注意:env() 是 Laravel 提供的辅助函数,底层调用 getenv() + $_ENV,它只在配置加载阶段有效;缓存配置后(php artisan config:cache)就不再读 .env,而是读缓存里的值。
- 必须用
env('DB_HOST', '127.0.0.1'),而不是$_ENV['DB_HOST']—— 后者在缓存后失效 - 敏感字段如
DB_PASSWORD、APP_KEY必须由env()获取,不可硬编码 - 运行
php artisan config:cache前,确保.env已就位或系统变量已生效,否则缓存会写入空值
为什么 php artisan config:cache 后改 .env 不生效?
因为缓存后的配置是纯 PHP 数组(写入 bootstrap/cache/config.php),完全绕过 env() 函数和 .env 文件解析逻辑。这是性能优化,也是安全设计——避免每次请求都重复读文件、做字符串解析。
- 上线后修改配置,必须重新运行
php artisan config:cache - CI/CD 流程中,应在部署脚本末尾加这一步,且确保此时
.env或系统变量已正确写入 - 若用 Envoyer、Laravel Forge 等工具,它们通常自动处理;自建部署需手动检查该步骤是否执行成功
- 调试时可用
php artisan tinker输入config('database.connections.mysql.password')确认当前生效值
.env,必须显式注入。哪怕 Nginx 配置了 fastcgi_param,也得确认 PHP 进程启动方式是否允许读取这些参数。










