.env.example是示例模板,不被加载;.env是实际生效配置文件,由phpdotenv自动加载到环境变量,修改错误会导致解析异常或返回null。

`.env.example` 是模板,`.env` 是实际生效的配置文件
根本区别在于:`.env.example` 不会被 Laravel 加载,它只是个示例;而 `.env` 文件一旦存在且格式正确,Laravel 启动时就会通过 vlucas/phpdotenv 自动加载其中所有变量到 $_ENV 和 getenv()。你改了 `.env.example`,对运行中的应用完全没影响;但改错 `.env`,比如少了个引号、多了个空格、用了中文等号,就可能触发 Dotenv\Parser\ParseException 或导致 env('DB_HOST') 返回 null。
为什么不能把 `.env` 提交到 Git
因为里面存的是真实环境密钥:APP_KEY、DB_PASSWORD、MAIL_PASSWORD 等。一旦提交,历史记录里永远留痕——即使删掉再 push,也能用 git log -p 挖出来。团队协作时,每个成员的本地数据库密码、测试邮箱账号都不同,硬塞同一个 `.env` 会导致「别人 clone 下来直接报错」。正确的做法是:
-
.gitignore里确保包含.env - 保留
.env.example并填好占位值(如DB_PASSWORD=your_password_here) - 部署脚本或 CI 流程中,用安全方式注入真实值(如 GitHub Secrets + envsubst,或服务器级环境变量)
`.env` 被覆盖的优先级顺序
Laravel 的 env() 函数不是只读 `.env` 文件,它会按固定顺序检查多个来源,靠后的值会覆盖前面的:
- 系统级环境变量(最高优先级,例如 Linux 下
export APP_DEBUG=true) - 服务器级(如 Apache 的
SetEnv或 Nginx 的fastcgi_param) -
.env文件内容(仅当未被上述两者定义时才生效)
这意味着:你在部署时完全不用碰 `.env` 文件,只要在服务器上设好 APP_ENV=production 和 APP_KEY,Laravel 就会跳过 `.env` 里的对应项。这也是为什么 .env.testing 只在 phpunit 或 php artisan --env=testing 时生效——它本质是靠运行时 APP_ENV 触发的另一套加载逻辑。
常见错误:`.env` 修改后不生效
改完 `.env` 却发现 config:cache 还是旧值,或者 php artisan tinker 里 env('APP_NAME') 没变,通常是因为:
- 执行过
php artisan config:cache—— 此命令会把所有配置(含env()调用结果)固化成 PHP 数组,后续不再读 `.env`;开发时应禁用该缓存,或每次改完都重跑php artisan config:clear -
.env文件编码不是 UTF-8 无 BOM,Windows 记事本保存容易带 BOM,导致解析失败 - 变量名拼写错误,比如写成
APP_KRY,而代码里调用env('APP_KEY'),此时返回默认值(第二个参数)或null - Web 服务器进程(如 PHP-FPM)没重启,旧进程还拿着旧的
$_ENV快照
真正要命的点是:这些错误往往不报错,只是静默返回默认值,比如 DB_DATABASE 缺失时自动 fallback 成 'homestead',结果连上错库还查不出问题。


















