sqlstate[hy000] [2003]本质是php客户端未触达mysql服务端,常见原因包括:mysql服务未运行、bind_address配置为127.0.0.1导致拒绝远程连接、防火墙/安全组拦截3306端口、tp6配置中hostname/hostport字段名写错、pdo_mysql未启用或socket路径不匹配。

报错 SQLSTATE[HY000] [2003] Can't connect to MySQL server,本质是 PHP 客户端根本没触达 MySQL 服务端——不是账号密码错,也不是 SQL 写错,而是网络层或服务层就断了。
MySQL 服务压根没起来或监听异常
最常被忽略的其实是服务状态本身。TP6 报 2003 时,第一反应不该改代码,而该确认 MySQL 进程是否真在跑、是否绑定了正确的地址。
- Linux 下执行
sudo systemctl status mysql或ps aux | grep mysqld,看有没有活跃进程 - 若服务停了,用
sudo systemctl start mysql启动;若启动失败,查日志:sudo journalctl -u mysql -n 50 --no-pager - 检查 MySQL 是否监听了外部请求:进 MySQL 执行
SHOW VARIABLES LIKE 'bind_address';,若值为127.0.0.1,则远程连接必然失败;需改为0.0.0.0或具体 IP,并重启服务 - 本地 CLI 能连(如
mysql -h 127.0.0.1 -u root -p)≠ TP6 能连——因为 TP6 默认走 TCP,而 CLI 可能走 socket;务必统一用-h 127.0.0.1测试,排除 socket 干扰
TP6 配置里 hostname 和 hostport 写法不匹配
ThinkPHP6 对连接参数名非常严格,写错字段名不会报明确错误,而是静默 fallback 到默认值(比如 hostname 写成 host,就会用 localhost + 默认 3306,但若你实际用的是非标端口,就直接失联)。
- 配置中必须用
'hostname' => '127.0.0.1',不能写'host';必须用'hostport' => '3307',不能写'port'或'database_port' - 若 MySQL 在 Docker 或云数据库上,
hostname不能填localhost(它会解析成容器/本机回环),得填宿主机 IP 或服务别名(如mysql) - 注意
hostport是字符串类型,不是整数;填3306有时会触发类型转换异常,稳妥写法是'hostport' => '3306'
防火墙或安全组拦住了 3306(或自定义端口)
开发环境常见于本地防火墙,生产环境多见于云厂商安全组策略。报 2003 却查不到 MySQL 日志记录,基本可锁定是这一层被拦截。
- Linux 本地防火墙:运行
sudo ufw status,若显示 active,加规则sudo ufw allow 3306 - 云服务器(阿里云/腾讯云等):进控制台 → 安全组 → 入方向规则,确保添加了允许来源 IP(或
0.0.0.0/0临时测试)访问端口 3306 的 TCP 规则 - Mac 用户注意:系统偏好设置 → 防火墙 → 防火墙选项 → 勾选“允许已签名的应用程序接收传入连接”,或临时关闭防火墙验证
- 不要只信
ping通——它走 ICMP;要用telnet 127.0.0.1 3306或nc -zv 127.0.0.1 3306真实测端口连通性
pdo_mysql 扩展未启用或 socket 路径错位
当 MySQL 走本地 socket 连接(常见于 macOS MAMP、某些 Linux 发行版默认配置),而 PHP 没配对 socket 路径,也会表现为 2003 —— 因为 PHP 尝试连一个不存在的 socket 文件。
- 先确认 MySQL socket 路径:登录 MySQL 执行
SHOW VARIABLES LIKE 'socket';,得到类似/var/run/mysqld/mysqld.sock - 再查 PHP 是否用了该路径:运行
php -i | grep "pdo_mysql.default_socket",若为空或路径不一致,编辑php.ini,取消注释并修正pdo_mysql.default_socket = /var/run/mysqld/mysqld.sock - 改完重启 PHP-FPM 或 Apache/Nginx;CLI 模式下还需确保 CLI 使用的 php.ini 和 Web 一致(可用
php --ini查看) - TP6 不支持在配置里直接指定 socket 路径,只能靠 php.ini 统一控制;想绕过 socket 改走 TCP?把
hostname明确设为127.0.0.1(而非localhost)即可
2003 错误真正的麻烦点在于它不告诉你卡在哪一层——可能是服务没开、端口没开、IP 写错、防火墙挡着、socket 路径不对,甚至 DNS 解析失败。排查时必须从底层网络开始,一层层向上验证,跳过任何一步都容易白忙活。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











