DB_HOST应填127.0.0.1而非localhost,因后者强制走Unix socket易报错,前者强制TCP更稳定;密码含特殊字符必须用单引号包裹;改.env后须执行php artisan config:clear刷新缓存。

DB_HOST 写 localhost 还是 127.0.0.1?
本地开发时,DB_HOST=localhost 看似合理,但 PHP 可能尝试走 Unix socket 而非 TCP,而 MySQL 若没配 socket 路径,就会报 No such file or directory;DB_HOST=127.0.0.1 强制走 TCP,更稳定。
常见踩坑点:
- Docker 环境下写
localhost相当于容器自己的 loopback,根本连不到宿主机或另一个容器 —— 必须填数据库服务名(如mysql) - MAMP/XAMPP 默认端口是
8889,不是3306,DB_PORT得手动对上 - 云服务器或远程 DB,
DB_HOST必须是公网 IP 或内网地址,且 MySQL 的bind-address需设为0.0.0.0或对应 IP
密码含 @、$、/ 等字符时怎么写?
DB_PASSWORD 里有特殊字符,不加引号或引号用错,Laravel 的 Dotenv 解析器会提前截断或变量展开,导致实际传给 PDO 的密码不对。
正确写法只有一种:DB_PASSWORD='pa@ss/w0rd'(单引号包裹)
错误写法包括:
-
DB_PASSWORD="pa@ss/w0rd"—— 双引号可能触发 shell 变量展开 -
DB_PASSWORD=pa@ss/w0rd——@会被 DSN 解析为分隔符,用户名变成pa,密码变成ss/w0rd -
DB_PASSWORD='%40pass%2Fword'—— URL 编码仅在DB_URL场景有效,.env里直接写编码反而错
改完 .env 为什么还是连不上?
Laravel 启动后会把 .env 加载进内存并缓存,改了文件不清理缓存,config('database.connections.mysql.host') 返回的仍是旧值。
必须执行:
-
php artisan config:clear—— 清掉配置缓存(不是cache:clear) - 如果启用了 OPCache,还得补一句
php artisan optimize:clear - 确认
APP_ENV没误设为production(该模式默认不加载.env) - 检查
.env文件权限和 BOM 头 —— Windows 记事本保存易带 BOM,PHP 读取失败但无提示
MySQL 8 报 SQLSTATE[HY000] [2054] 怎么办?
这是 MySQL 8 默认用 caching_sha2_password 插件,而 Laravel 5.5 + 低版本 PHP(
验证方式:在 tinker 里执行 DB::connection()->getPdo(),若抛出该错误码,基本锁定此问题。
临时解法(推荐):
- 登录 MySQL 执行:
ALTER USER 'your_user'@'%' IDENTIFIED WITH mysql_native_password BY 'your_password'; FLUSH PRIVILEGES; - 注意:不能只改
'your_user'@'localhost',得匹配你实际用的DB_HOST(比如'your_user'@'127.0.0.1')
长期方案是升级 PHP,但 Laravel 5.5 官方已停止维护,不建议强推新版本依赖。
最常被跳过的其实是 MySQL 用户授权粒度和认证插件这两层 —— 它们不报明确错误,日志里只显示 “Connection refused” 或空异常,得靠排除法一层层往下试。


















