先确认mysql是否监听3306端口:linux执行ss -tlnp | grep :3306,若无输出说明未监听;若有输出需检查host是否为127.0.0.1(仅本地)或0.0.0.0(支持远程),并核对my.cnf中port与bind-address配置一致且重启服务。

检查 MySQL 是否监听 3306 端口
Connection refused 错误中,约 60% 是因为 MySQL 根本没在目标端口上监听。别急着改 PHP 代码,先确认服务端有没有“开门”。
Linux 下运行:netstat -tlnp | grep :3306 或更轻量的 ss -tlnp | grep :3306。如果无输出,说明 mysqld 没绑定 3306 —— 即使服务状态显示 active,也可能只监听了 socket 或其他端口。
- 若输出中 host 是
127.0.0.1:3306,表示仅接受本地 TCP 连接;若为*:3306或0.0.0.0:3306,才支持远程(含本机其他进程) - 若看到
mysqld进程但端口是:3307或其他数字,说明配置了非默认端口,PHP 的mysqli_connect()必须显式传入$port参数,不能依赖默认值 - macOS 用户注意:
brew services list显示 mysql 状态后,仍需用lsof -i :3306验证端口占用,Homebrew 启动的实例有时监听路径而非端口
确认 my.cnf 中 port 和 bind-address 配置一致
MySQL 的端口行为受两个关键配置项控制:port 决定监听哪个数字端口,bind-address 决定监听哪个 IP 地址。二者不匹配会导致“服务在跑,但连不上”的假象。
查配置位置:mysql --help | grep "Default options" 找到实际生效的 my.cnf 路径(常见于 /etc/mysql/my.cnf、/usr/etc/my.cnf 或 /opt/homebrew/etc/my.cnf)。
-
[mysqld]段下必须有port = 3306(或你期望的端口号),且不能被注释 -
bind-address若设为localhost,MySQL 会尝试走 Unix socket,**不是 TCP**;此时telnet 127.0.0.1 3306必然失败 —— 应改为127.0.0.1或0.0.0.0 - 改完配置必须重启服务:
systemctl restart mysql(Debian/Ubuntu)或brew services restart mysql(macOS),reload 不生效
PHP 连接时端口参数不能省略或错位
mysqli_connect() 函数签名是 mysqli_connect($host, $user, $password, $database, $port)。第 5 个参数 $port 是可选的,但一旦 MySQL 改了端口,它就变成必填项 —— 漏掉或传错位置,连接直接 fallback 到 3306,报 Connection refused。
- 错误写法:
mysqli_connect('127.0.0.1', 'root', 'pass', 'test')→ 默认用 3306,但 MySQL 实际监听 3307 - 正确写法:
mysqli_connect('127.0.0.1', 'root', 'pass', 'test', 3307) - PDO 更容易踩坑:
mysql:host=127.0.0.1;dbname=test没写port=3307,同样连 3306;得写成mysql:host=127.0.0.1;port=3307;dbname=test - 环境变量或配置文件里拼接 DSN 时,注意空格和分号闭合,
port=3307;多了个分号会导致解析失败
用 telnet 或 nc 快速验证端口连通性
在 PHP 服务器本机执行 telnet 127.0.0.1 3306(或 nc -zv 127.0.0.1 3306)是最直接的判断方式:通了,问题在账号/权限/代码;不通,问题一定在服务、端口或网络层。
- 如果
telnet报 “Connection refused”,而netstat又显示 3306 在监听,大概率是bind-address配错了(比如写了localhost) - 如果
telnet报 “timeout” 或卡住,说明防火墙拦截(ufw status或iptables -L查 3306)、云服务器安全组未放行,或 MySQL 根本没监听该 IP - Docker 容器内 PHP 连宿主 MySQL 时,host 不能写
127.0.0.1(那是容器自己),得用宿主真实 IP 或host.docker.internal(Docker Desktop)或docker0网桥地址
端口问题最麻烦的点在于:它藏在服务配置、网络策略、客户端参数三层之间。一个 netstat 加一个 telnet 就能切掉 80% 的可能性,但很多人跳过这步直接翻 PHP 代码 —— 结果调半天发现 MySQL 压根没监听那个端口。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











