mysql服务端必须监听非本地地址,即修改bind-address=0.0.0.0(或指定ip)并重启服务;创建限定来源ip的用户并授权;放行系统防火墙及云平台安全组3306端口。

MySQL服务端必须监听非本地地址
PHP 8.5.5 连不上远程 MySQL,90% 的情况不是代码问题,而是 MySQL 根本没“听见”你的连接请求。默认配置下 bind-address = 127.0.0.1,只响应本机请求,外部 IP 包直接被丢弃。
- 编辑 MySQL 配置文件(常见路径:
/etc/mysql/mysql.conf.d/mysqld.cnf或/etc/my.cnf),找到bind-address行,改为:bind-address = 0.0.0.0(生产环境建议填 PHP 服务器的公网 IP,更安全) - 重启服务:
sudo systemctl restart mysql - 验证是否生效:
sudo netstat -tlnp | grep :3306,输出中必须含*:3306,而非127.0.0.1:3306
必须创建限定来源 IP 的数据库用户
别碰 root@'%',也别用 UPDATE user SET host = '%' 改 root 权限——云平台(阿里云、腾讯云、GCP)会拦截这种操作,MySQL 8+ 严格模式也会拒绝。
- 登录 MySQL(仅限数据库服务器本地):
mysql -u root -p - 执行(把
192.168.1.100换成你 PHP 服务器的真实公网 IP):CREATE USER 'php_app'@'192.168.1.100' IDENTIFIED BY 'strong_password_2026';<br>GRANT SELECT, INSERT, UPDATE ON mydb.* TO 'php_app'@'192.168.1.100';<br>FLUSH PRIVILEGES;
- 不授
ALL PRIVILEGES,最小权限原则;不用'php_app'@'%',除非你明确需要任意 IP 连接
防火墙和云平台安全组常是最后一道拦路虎
能 ping 通不代表能连上 MySQL —— ping 走 ICMP,MySQL 走 TCP 3306 端口,两者完全独立。
- Linux 服务器防火墙放行:
sudo ufw allow from 192.168.1.100 to any port 3306(Ubuntu)或sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.1.100" port port="3306" protocol="tcp" accept'(CentOS) - 云平台(如腾讯云 CVM、阿里云 ECS)必须在「安全组」里添加入方向规则:协议 TCP,端口 3306,源 IP 填 PHP 服务器公网 IP(别填
0.0.0.0/0,仅测试可用) - 本地终端验证端口连通性:
telnet your-mysql-ip 3306或nc -zv your-mysql-ip 3306,有Connected才算过这一关
PDO 连接字符串必须显式声明 charset 和 port
PHP 8.5.5 对字符集更敏感,utf8 已被弃用,utf8mb4 是唯一可靠选项;DSN 中不写 port 时默认 3306,但显式写出更稳妥,避免代理或中间件干扰。
- 不要用
localhost或域名当host——前者连本地,后者 DNS 解析失败会导致几秒卡顿且报错模糊 - 推荐 PDO 写法(带异常模式):
$pdo = new PDO("mysql:host=203.0.113.45;port=3306;dbname=mydb;charset=utf8mb4", "php_app", "strong_password_2026", [<br> PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,<br>]); - 确认扩展已启用:
php -m | grep -E '^(pdo|mysqli)',缺则装:sudo apt install php-pdo php-mysql(Ubuntu)
实际连通前,三个环节缺一不可:MySQL 监听正确地址、用户权限绑定到具体 IP、3306 端口在系统和云平台层面都放行。任何一环漏掉,PDOException 或 mysqli_connect_error() 报的错都会指向“拒绝连接”,但真正原因藏在服务端配置里。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











