努力
加油

在非标准端口上运行MySQL时,WordPress怎么配置连接?

WordPress 连接非标准端口 MySQL 其实是个非常经典但容易让人踩坑的场景。很多人以为改个 wp-config.php 就能搞定,结果发现连上了数据库却死活进不去后台,或者报“Establishing a database connection”错误。

核心问题在于:WordPress 原生的 DB_HOST 配置项只支持主机名或 IP,不支持直接拼接端口号。 如果你写成 '127.0.0.1:3307',PHP 的 mysqli 或 PDO 驱动通常无法正确解析这个字符串,导致连接失败。

要解决这个问题,主要有三种靠谱的方案,按推荐程度排序:

方案一:使用 Unix Socket 或显式指定端口(最稳定)

这是官方文档中隐含支持的方式,但需要一点技巧。在 wp-config.php 中,DB_HOST 不仅仅接受主机名,它还接受一个数组格式(虽然文档没大肆宣传,但底层代码是支持的),或者通过修改 PHP 的 mysqli 默认行为。

步骤如下:

  1. 打开你的 wp-config.php 文件。

  2. 找到 DB_HOST 定义。

  3. 不要写成 'localhost:3307' 或 '127.0.0.1:3307'。

  4. 改为以下两种写法之一:

    写法 A:显式指定端口(推荐)

    define( 'DB_HOST', '127.0.0.1:3307' ); 
    // 注意:这取决于你的 PHP 版本和 MySQL 驱动。
    // 较新的 PHP 8.x + MySQLi 通常能自动识别冒号后的端口。
    // 如果报错,请用写法 B。

    写法 B:通过 PHP 扩展参数传递(更稳妥)
    WordPress 的 wpdb 类允许你在 DB_HOST 中使用特殊字符来触发不同的连接方式。但对于非标准端口,最通用的“黑客”做法是利用 mysqli_real_connect 的参数特性。不过,最简单且兼容性最好的方法是:

    实际上,对于大多数现代 LAMP/LNMP 环境,直接在 DB_HOST 写 127.0.0.1:3307 是有效的,前提是:

    • 你使用的是 MySQLi 扩展(PHP 默认)。
    • 你没有强制使用 localhost(因为 localhost 会优先尝试 Unix Socket,而不是 TCP/IP,从而忽略端口)。

    关键修正:
    将 DB_HOST 从 localhost 改为 127.0.0.1 或具体的服务器 IP,并加上端口。

    define('DB_HOST', '127.0.0.1:3307');

    注意:这里必须用 127.0.0.1 而不是 localhost。因为 localhost 在 Linux/Unix 系统中默认走 Unix Socket 文件,而 Socket 文件通常绑定在标准路径上,不监听 TCP 端口。改成 IP 地址后,PHP 才会通过 TCP/IP 协议连接,此时才能识别端口号。

方案二:使用 SSH 隧道(最安全,适合云主机)

如果你的 MySQL 在非标准端口,且出于安全考虑只允许内网访问,或者你想避免暴露端口到公网,SSH 隧道是最佳实践。

原理:
本地机器 -> SSH 连接到云服务器 -> 转发本地某个端口(如 3306)到云服务器的 MySQL 端口(如 3307)。

操作步骤:

  1. 在你的本地电脑(开发机)上建立 SSH 隧道:

    ssh -L 3306:127.0.0.1:3307 user@your-server-ip

    这条命令的意思是:把你本地的 3306 端口,通过 SSH 加密通道,转发到远程服务器的 127.0.0.1 的 3307 端口。

  2. 保持终端开启,然后正常配置 WordPress:

    define('DB_HOST', 'localhost:3306'); // 或者直接用 localhost

    这样 WordPress 认为它连接的是本地标准端口,实际流量被 SSH 转发到了非标准端口。

优点:

  • 无需修改 WordPress 核心代码逻辑。
  • 数据加密传输,安全性高。
  • 兼容性好,任何版本的 PHP/MySQL 都能用。

方案三:修改 MySQL 配置文件(不推荐,但最简单)

如果你能控制 MySQL 服务器本身,最直接的办法其实是把端口改回默认的 3306。

操作:

  1. 登录 MySQL 服务器。
  2. 编辑 /etc/mysql/my.cnf 或 /etc/my.cnf。
  3. 找到 port = 3307,改为 port = 3306。
  4. 重启 MySQL 服务:systemctl restart mysqld。

为什么我不推荐?

  • 很多云厂商的安全组策略、防火墙规则可能已经针对特定端口做了限制。
  • 如果同一台服务器上还有其他服务依赖非标准端口,改回去会影响其他服务。
  • 违背了“最小权限原则”,非标准端口本身就是一种隐蔽性安全措施(Security through Obscurity)。

常见坑点排查

如果你改了 DB_HOST 还是连不上,请按以下顺序检查:

  1. 确认是 localhost 还是 127.0.0.1

    • localhost -> Unix Socket -> 忽略端口 -> 失败。
    • 127.0.0.1 -> TCP/IP -> 识别端口 -> 成功。
    • 务必确保 DB_HOST 不以 localhost 开头。
  2. 检查 MySQL 是否监听该端口

    netstat -tuln | grep 3307
    # 或
    ss -tuln | grep 3307

    确保输出中有 0.0.0.0:3307 或 :::3307,说明 MySQL 正在监听该端口。

  3. 检查防火墙/安全组

    • 如果是云服务器(阿里云、腾讯云等),记得在控制台的安全组里放行 3307 端口的入方向规则,协议选择 TCP。
    • 服务器内部的 iptables 或 firewalld 也要放行。
  4. PHP 错误日志
    查看 php-fpm.log 或 error_log,通常会给出类似:

    “Can’t connect to MySQL server on ‘127.0.0.1’ (111)”
    这表示网络不通或端口不对。

    “Access denied for user…”
    表示连接成功,但账号密码错。

  5. SELinux(CentOS/RHEL 系统)
    如果启用了 SELinux,可能会阻止 Apache/Nginx 进程连接非标准端口。可以尝试临时关闭测试:

    setenforce 0

    如果关闭后正常,则需要配置 SELinux 策略允许 httpd 连接网络端口:

    setsebool -P httpd_can_network_connect_db 1

总结

对于生产环境,推荐使用方案一中的 127.0.0.1:3307 写法,并确保使用 127.0.0.1 而非 localhost。这是最直接、改动最小的方式。

如果涉及跨地域或高安全要求,方案二(SSH 隧道) 是更专业的选择,尤其适合开发和运维人员日常维护时使用。