phpEnv连不上远程MySQL,根本原因在远程MySQL配置:需确保其bind-address设为0.0.0.0、用户授权含'%'或对应IP、云服务器/防火墙/安全组均放行3306端口,且PHP代码中host不能写localhost而须用IP或域名。

phpEnv 连不上远程 MySQL?先确认它连的是哪台 MySQL
phpEnv 是本地开发环境,它本身不提供远程数据库服务——你写的 mysqli_connect() 或 PDO 里的 host 参数,决定它试图连接谁。很多人误以为“phpEnv 要配远程权限”,其实该配的是**目标远程服务器上的 MySQL**,不是 phpEnv 自己的 MySQL。
常见错误现象:mysqli_connect(): (HY000/2003): Can't connect to MySQL server on 'xxx' (111) 或 Connection refused。
- 如果 phpEnv 本机也装了 MySQL(比如默认启用了),而你代码里写的是
'localhost',那它连的是自己本地的 MySQL,不是远程的——必须改 host - 用
telnet your-remote-ip 3306或nc -zv your-remote-ip 3306先测试通不通。不通,说明网络层卡住,和 phpEnv 无关 - phpEnv 的 PHP 配置(如
php.ini)一般不用动,它不影响远程连接能力,只影响本地扩展加载
远程 MySQL 必须开放的三项配置
缺一不可,顺序无关,但漏一个就白调:
-
bind-address:登录远程服务器,查
/etc/mysql/mysql.conf.d/mysqld.cnf(Ubuntu/Debian)或/etc/my.cnf(CentOS/宝塔),确认bind-address不是127.0.0.1;改成0.0.0.0或直接注释掉该行,然后sudo systemctl restart mysql -
用户权限:进 MySQL 执行
SELECT host,user FROM mysql.user WHERE user='your_user';,结果里必须有%或对应 IP 的行;没有就执行GRANT ALL ON mydb.* TO 'your_user'@'%' IDENTIFIED BY 'your_pass'; FLUSH PRIVILEGES; -
端口放行:检查远程服务器防火墙(
ufw status/firewall-cmd --state)、宝塔「安全」页的端口放行、云平台(阿里云/腾讯云)安全组——三者都要开3306/tcp,不能只开一个
PHP 代码里 host 写 localhost 就一定失败
这是最隐蔽也最常踩的坑:localhost 在 MySQL 客户端协议中是特殊值,强制走 Unix socket,哪怕你目标数据库真在另一台机器上,PHP 也会忽略 port、忽略 DNS 解析,直接尝试连本地 socket 文件——报错却像“密码错”或“拒绝访问”,非常误导。
立即学习“PHP免费学习笔记(深入)”;
- 正确写法:
mysqli_connect('192.168.1.100', 'user', 'pass', 'db', 3306)或mysqli_connect('db.example.com', ...) - 哪怕远程数据库和 phpEnv 在同一台物理机,只要你想走 TCP(比如调试时绕过 socket 权限限制),也得写
127.0.0.1,不能写localhost - PDO 更严格:DSN 中必须显式写
host=xxx和port=3306,漏 port 且远程 MySQL 改了端口(如 3307),会静默超时,不报具体错误
MySQL 8.0 连接失败?大概率是加密插件不兼容
phpEnv 自带的 PHP(尤其旧版本)默认不支持 MySQL 8.0 的 caching_sha2_password 插件,连上去直接报 Authentication plugin 'caching_sha2_password' cannot be loaded 或 Navicat 的 2059 错误。
- 临时解决(开发用):进远程 MySQL,重置用户认证方式:
ALTER USER 'your_user'@'%' IDENTIFIED WITH mysql_native_password BY 'your_pass'; FLUSH PRIVILEGES; - 长期建议:升级 phpEnv 中的 PHP 到 7.4+ 并确认已启用
mysqlnd驱动,再配合新版 MySQL 客户端库 - 别碰
skip-grant-tables:这个配置会导致所有用户免密登录,重启后若忘记删,等于裸奔
真正卡住的点往往不在代码,而在远程 MySQL 的 host 字段值、bind-address 是否生效、以及三个层级的防火墙有没有全开——调的时候按这三块挨个验证,比反复改 PHP 配置高效得多。



















