报错sqlstatehy000时,应先确认mysql服务是否真正运行并监听端口:linux用systemctl status mysql和netstat -tulnp | grep :3306检查,windows查services.msc中服务状态,docker需docker ps及容器内ss命令验证;同时注意localhost默认走socket而非tcp,可改用127.0.0.1直连测试。
![php连接数据库报sqlstate [hy000] [2002]连接拒绝](https://img.php.cn/upload/article/001/503/042/179092614736360.png?x-oss-process=image/resize,p_40)
确认 MySQL 服务是否真在监听
报 SQLSTATE[HY000] [2002] 时,第一反应不该是改代码,而是看数据库进程有没有真正跑起来、有没有对外“张嘴”。很多情况下服务看似启动了,但实际没监听任何端口。
- Linux 下执行
systemctl status mysql或systemctl status mysqld,确认状态是active (running),不是activating或failed - 接着查监听:运行
netstat -tulnp | grep :3306(或你配置的其他端口),输出里必须有mysql或mysqld进程绑定到对应地址和端口 - Windows 用户别只信任务管理器——进
services.msc找 “MySQL” 或 “MySQL80”,右键“属性”,看“启动类型”是否为“自动”,且“服务状态”显示“正在运行” - 如果用 Docker,
docker ps看容器是否 Up,再进容器执行ss -tlnp | grep 3306(Alpine 可用netstat -tlnp)
检查连接参数是否被解析成 socket 而非 TCP
localhost 在 PHP 的 PDO / mysqli 中是个“陷阱词”:它不等于 127.0.0.1。多数 Unix-like 系统下,localhost 会强制走 Unix socket 文件(如 /var/run/mysqld/mysqld.sock),而 127.0.0.1 才走 TCP。一旦 socket 路径错、权限不对或文件不存在,就会报 [2002],且错误信息里常带 No such file or directory。
- 临时把配置里的
hostname从localhost改成127.0.0.1,立刻重试 - 如果改完通了,说明问题出在 socket 路径——检查 MySQL 配置中
socket项(my.cnf的[mysqld]和[client]段),确保两端一致 - Docker 场景下,应用容器连数据库容器时,绝不能写
localhost——必须用docker-compose.yml里定义的服务名(如db) - PHP 8.0+ 默认抛异常,记得加
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,否则错误被静默吞掉
验证网络与防火墙是否拦住了 3306
即使服务跑了、参数对了,中间还有网络链路和策略可能掐断连接。尤其在云环境、Docker 或虚拟机里,这个环节最容易漏查。
- 本地测试用
telnet 127.0.0.1 3306(Windows)或nc -zv 127.0.0.1 3306(Linux/macOS)直连端口,不通就说明服务没监听或被拦截 - Linux 防火墙:运行
sudo ufw status(Ubuntu)或sudo firewall-cmd --state(CentOS/RHEL),确认 3306 已放行 - 云服务器(如阿里云、腾讯云):安全组规则必须显式开放入方向 3306 端口,且源 IP 要包含你的应用服务器内网 IP(不是公网 IP)
- SELinux(CentOS 7+/RHEL 8+):可能阻止 PHP-FPM 访问网络,临时关闭验证:
sudo setenforce 0;若恢复后仍需启用,用setsebool -P httpd_can_network_connect 1
绕过框架,用命令行直连验证底层能力
框架配置再复杂,最终都落到一条 DSN 和系统级连接能力上。命令行直连能快速排除是“PHP 层问题”还是“环境层问题”。
- 执行:
mysql -h 127.0.0.1 -P 3306 -u your_user -p—— 注意用127.0.0.1,不用localhost,避免 socket 干扰 - 如果这步失败,问题一定不在 PHP 代码或框架,而在 MySQL 服务、用户权限、网络或防火墙
- 如果成功,再比对你的 PHP DSN:检查
host、port、user、password是否完全一致,特别注意DB_PASSWORD含@、/、:时需 URL 编码 - 确认
pdo_mysql扩展已加载:php -m | grep pdo_mysql必须有输出;Docker Alpine 镜像要额外装apk add php82-pdo_mysql(版本号需匹配)
database 是有效主机名,宿主机上却根本不存在;host.docker.internal 在 Linux Docker Desktop 需手动配置;localhost 在 CLI 测试时指向宿主机,但在容器里指向自己——这些细节不抠清楚,查半天日志也白搭。php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











