connection refused 错误本质是 php 进程未连上数据库服务,主因是数据库未监听、防火墙拦截或 docker 网络配置错误(如 db_host 填 localhost 而非服务名),需检查服务状态、bind-address、安全组、.env 配置准确性、认证插件兼容性及 config/database.php 覆盖逻辑。

Connection refused 错误说明
绝大多数 Laravel 数据库连接失败,报 Connection refused,本质是 PHP 进程压根没连上数据库服务——不是密码错、不是配置漏,而是 MySQL/PostgreSQL 根本没在监听,或者被防火墙/网络策略拦了。
常见现象:本地 php artisan migrate 报错,但 mysql -u root -p 命令能正常登录;Docker 环境里 artisan 连不上 db 容器,但容器间 ping db 能通。
- 检查数据库服务是否真正运行:
sudo systemctl status mysql(Linux)或brew services list | grep mysql(macOS) - Docker 用户重点看
DB_HOST:Laravel 容器里不能填localhost,得填 Docker Compose 中定义的服务名,比如db - MySQL 8.0+ 默认绑定
127.0.0.1,不响应外部请求;需确认bind-address配置为0.0.0.0或注释掉 - 云服务器(如阿里云、腾讯云)必须检查安全组规则,开放对应端口(MySQL 默认
3306)
.env 中 DB_* 配置项常见错位
Laravel 读取数据库配置完全依赖 .env,config/database.php 只是兜底和组装逻辑。很多“改了配置还不生效”,其实是环境变量根本没加载或写错字段名。
典型错误:把 DB_DATABASE 写成 DB_NAME,或漏掉 DB_PORT 导致用默认 3306 去连一个跑在 3307 的实例。
-
DB_CONNECTION必须是mysql、pgsql、sqlite之一,大小写敏感,MySQL会静默失败 -
DB_PASSWORD含特殊字符(如@、/、:)时,必须用单引号包裹:DB_PASSWORD='pa@ss/w0rd' - 修改
.env后必须清缓存:php artisan config:clear;否则 Laravel 仍用旧配置 - 部署到生产环境时,确保 Web 服务器用户(如
www-data)有读取.env文件权限
MySQL 8.0+ 认证插件不兼容
Laravel 9+ 默认支持 caching_sha2_password,但低版本 PDO 或某些宿主机(尤其旧版 XAMPP/MAMP)只认 mysql_native_password。此时连接会卡住或报 SQLSTATE[HY000] [2054] The server requested authentication method unknown to the client。
这不是 Laravel 的锅,是 MySQL 服务端和 PHP 客户端认证协议对不上。
- 临时解决:登录 MySQL,执行
ALTER USER 'your_user'@'%' IDENTIFIED WITH mysql_native_password BY 'your_password'; - 长期建议:升级 PHP 到 7.4+ 并确认
pdo_mysql扩展已启用(php -m | grep pdo_mysql) - 若用 Docker,可在 MySQL 容器启动时加参数:
-e MYSQL_DEFAULT_AUTHENTICATION_PLUGIN=mysql_native_password
config/database.php 覆盖逻辑易被忽略
很多人以为改了 .env 就万事大吉,但 Laravel 允许在 config/database.php 里硬编码覆盖值,比如写死 'port' => 3308。一旦这里和 .env 冲突,以 PHP 数组字面量为准。
更隐蔽的是,有些团队会在 AppServiceProvider 里动态改 Config::set('database.connections.mysql.port', ...),调试时根本想不到。
- 排查时先运行
php artisan tinker,输入config('database.connections.mysql.host'),看返回值是否和.env一致 - 搜索整个项目:
grep -r "Config::set.*database" app/和grep -r "'port' =>" config/database.php - SQLite 场景下容易误配
DB_DATABASE为绝对路径却忘了加database/前缀,导致文件创建在根目录或报No such file
最麻烦的不是连不上,而是连上了却连错库——比如本地 .env 指向测试库,但 config/database.php 里 database 键值被硬编码成 production_db,这种错连上也查不到数据,debug 成本最高。











