PHP连接非标端口MySQL需显式指定端口:mysqli用第4参数(整数)并设host为127.0.0.1;PDO在DSN中用port=且置于host后dbname前;避免localhost导致socket直连。

PHP 连接带端口的 MySQL 用 mysqli 或 PDO 指定端口
PHP 默认连接 MySQL 是走本地 socket(Unix)或 3306 端口,但如果你的 MySQL 实例监听在非标端口(比如 3307、4306),必须显式传入端口号,否则会连错或报错(如 Connection refused 或 Can't connect to MySQL server)。
关键点:端口号不是拼在主机名后面(如 "localhost:3307" 在某些场景下不可靠),而是作为独立参数传入。
-
mysqli构造函数第 4 个参数是$port,必须是整数(不能是字符串) -
PDO的 DSN 中用port=查询参数,且必须写在host=后面、dbname=前面 - 如果用
127.0.0.1而非localhost,MySQL 会强制走 TCP,此时端口才真正生效;localhost在 Linux 下可能绕过端口直连 socket
mysqli 指定端口连接 MySQL 的正确写法
错误写法:new mysqli("localhost:3307", $user, $pass, $db) —— 这里的 :3307 不会被解析为端口,而是当成主机名一部分,连接必然失败。
正确写法必须把端口作为第 4 个参数传入,且前 3 个参数不能缺位:
立即学习“PHP免费学习笔记(深入)”;
$host = '127.0.0.1'; // 强制走 TCP
$port = 3307; // 必须是整数
$mysqli = new mysqli($host, $user, $pass, $db, $port);
if ($mysqli->connect_error) {
die('Connect Error (' . $mysqli->connect_errno . ') ' . $mysqli->connect_error);
}
- 如果省略第 5 个参数(
$socket),第 4 个参数才被识别为端口 - 若你同时需要指定 socket 文件(如
/tmp/mysql.sock),那就不能用第 4 个参数传端口,得改用 DSN 方式或 PDO - 注意:
$host用127.0.0.1比localhost更可控,尤其在 Docker 或远程部署时
PDO 连接非标端口 MySQL 的 DSN 写法
PDO 的 DSN 格式更灵活,但顺序和键名必须严格。端口必须用 port=,且不能漏掉 host=(即使值是 127.0.0.1):
$dsn = 'mysql:host=127.0.0.1;port=3307;dbname=test;charset=utf8mb4';
$pdo = new PDO($dsn, $user, $pass, [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
]);
- 不要写成
mysql://user:pass@127.0.0.1:3307/test—— PDO 不支持这种 URL 风格 DSN -
charset=utf8mb4推荐加上,避免中文乱码;不加也不报错,但可能隐性出问题 - 如果端口写错或服务未监听,PDO 会抛出
PDOException,错误信息里通常含Connection refused或具体 errno
常见连不上端口的三个实际原因
很多“指定了端口还是连不上”的问题,其实和 PHP 代码无关,而是环境配置卡住:
- MySQL 服务根本没监听那个端口:检查
my.cnf中port = 3307是否存在,且bind-address允许访问(如0.0.0.0或127.0.0.1) -
防火墙/安全组拦截:Linux 上用
sudo ss -tlnp | grep :3307看端口是否真在 LISTEN;云服务器还要查安全组规则 - PHP 容器或 CLI 环境 DNS 解析异常:比如在 Docker 中用
localhost指向容器自身,而非宿主 MySQL;此时应改用宿主网关 IP(如172.17.0.1)或 docker network 别名
端口本身只是个数字,但连通性是网络、配置、权限三层叠加的结果。别只盯着 PHP 代码改,先确认 MySQL 确实在那个端口上“开着门”。











