laravel数据库连接失败的首要原因是.env配置未生效,因database.php中硬编码host会覆盖.env值,且php-fpm、docker环境变量透传缺失、缓存未清除或.env文件格式错误(如空格)亦常见。

DB_HOST 配置被 database.php 覆盖了
Laravel 不是直接读取 .env 里的 DB_HOST 就去连数据库,而是先通过 database.php 的配置数组组装连接参数。这个文件里默认没写 port,也**没显式声明 host 来源**,但关键点在于:'host' => env('DB_HOST', 'localhost') 这行本身没问题,可一旦你改过 database.php(比如手动加了 'host' => '127.0.0.1'),它就彻底绕过了 .env。
常见误操作:
- 复制别人项目时直接用了修改过的
config/database.php,里面硬编码了 host - 为调试临时改了
database.php,后来忘了还原 - 升级 Laravel 后没对比新旧
database.php,残留了旧版覆盖逻辑
验证方法:在 database.php 的 mysql 数组开头加一行 dd(env('DB_HOST'));,再运行 php artisan tinker。如果输出是 null 或旧值,说明 .env 没加载;如果输出正确但连接仍失败,大概率是这里被覆盖了。
PHP-FPM 或 Web 服务器没把环境变量透传给 PHP
在 Nginx + PHP-FPM 环境下,.env 文件靠 vlucas/phpdotenv 加载,而它依赖 PHP 能读到 $_ENV 或 getenv()。但 PHP-FPM 默认不自动继承系统环境变量,尤其 Docker 或 systemd 部署时更常见。
检查和修复步骤:
- 进容器或服务器执行
printenv | grep DB_HOST,确认系统层变量存在 - 查 PHP-FPM 配置(如
/etc/php/*/fpm/pool.d/www.conf),确保有类似env[DB_HOST] = $DB_HOST的行 - 若用 Docker,启动命令必须带
-e DB_HOST=...或--env-file .env,不能只靠 COPY .env 到镜像里 - 重启 PHP-FPM 和 Web 服务(
systemctl restart php*-fpm nginx)
缓存没清干净,还是在用旧配置
php artisan config:clear 只删 bootstrap/cache/config.php,但有些部署会额外生成 bootstrap/cache/services.php 或 compiled.php,它们也可能固化了旧的数据库配置。
彻底清理建议:
- 删掉整个
bootstrap/cache/目录(别只删单个文件) - 运行
php artisan config:clear && php artisan cache:clear && composer dump-autoload - 如果用过
php artisan optimize(Laravel 5.5 以前),还要删bootstrap/cache/compiled.php - 最后验证:在路由里写
return response()->json(['db_host' => config('database.connections.mysql.host')]);,看返回是否是你改后的值
Docker 或 CI/CD 构建时 .env 根本没进容器
很多人把 .env 放进 .dockerignore(怕泄露密钥),结果容器启动时 phpdotenv 找不到文件,全退回到 database.php 里的默认值(localhost)。
安全又可用的做法:
- 构建阶段不 COPY
.env,运行阶段用-e参数注入关键变量 - 或用
--env-file挂载,但确保该文件权限为 600、不被 Git 跟踪 - 检查容器内是否存在
.env:docker exec -it your-app ls -la | grep .env - 如果用 Kubernetes,确认 ConfigMap 或 Secret 已挂载到容器对应路径,且 key 名与
.env里一致(如DB_HOST)
最常被忽略的一点:即使 .env 存在,如果文件里某行末尾多了空格(比如 DB_HOST= 127.0.0.1),phpdotenv 会把它解析成空字符串——这种隐形错误只能靠 cat -A .env 查看控制符来发现。











