Connection refused 根本原因是 PDO 连接被操作系统拒绝,主因是 MySQL 服务未启动、Docker 网络配置错误(DB_HOST 应填容器名而非 localhost)、或 MySQL 8 的 caching_sha2_password 认证插件不兼容。

连接失败不是 Laravel 的 bug,是底层链路断了。先确认服务在跑、参数对得上、认证能通过,再谈框架配置。
DB_HOST 写 localhost 还是 127.0.0.1?
在 Docker 或某些 Linux 环境下,localhost 会让 PHP 尝试走 Unix socket,但 MySQL 可能没配 socket 路径,结果报 No such file or directory;而 127.0.0.1 强制走 TCP,更可靠。
- 本地开发用 MAMP/XAMPP:优先试
127.0.0.1,端口留意是不是8889(MAMP 默认) - Docker 场景:DB_HOST 必须写数据库容器名(如
mysql),不能写localhost或127.0.0.1(后者指向宿主机,不是容器) - 远程数据库:确保防火墙放行
DB_PORT,且 MySQL 用户授权包含该 IP(比如'user'@'1.2.3.4')
Connection refused 的三个真实原因
这个错误根本没到 Laravel 认证层,PDO 连接时就被操作系统拒绝了。
-
mysqld进程压根没启动:Mac 上运行brew services list | grep mysql,Linux 上执行systemctl status mysqld - Docker 容器没跑或端口没映射:
docker ps看容器状态,确认有类似-p 3306:3306的映射 - MySQL 用户权限不匹配:DB_HOST=127.0.0.1 时,用户必须是
'user'@'127.0.0.1',而不是仅'user'@'localhost';补授权用GRANT ALL ON db.* TO 'user'@'127.0.0.1' IDENTIFIED BY 'pass'; FLUSH PRIVILEGES;
MySQL 8 的 caching_sha2_password 导致静默失败
PHP 连不上、没报具体插件名、只卡在超时或抛 SQLSTATE[HY000] [2054] —— 八成是这个。
- 老版本 PHP(caching_sha2_password
- 别改 Laravel 配置,这是 MySQL 用户级认证问题
- 临时解法:
ALTER USER 'your_user'@'%' IDENTIFIED WITH mysql_native_password BY 'your_password'; - 长期方案:升级 PHP 到 7.4+,并确认
php -i | grep mysqlnd输出里含sha256_password或caching_sha2_password
怎么快速验证 .env 配置是否真生效?
别一上来就 php artisan migrate,先做两步轻量验证:
- 检查 PDO 驱动:运行
php -r "var_dump(PDO::getAvailableDrivers());",输出里必须有mysql - 直连测试:运行
php artisan tinker,输入DB::connection()->getPdo();—— 成功返回一个PDO实例;报错则说明参数或服务层仍有问题 - 注意:
tinker里执行完记得输exit,否则会卡住终端
最常被跳过的其实是「数据库用户权限」和「MySQL 8 认证插件」这两层——它们不报明确错误,只让连接无限等待或直接断开,排查时容易绕远路。


















