PDO是PHP 7.1连接PolarDB MySQL版最稳妥方式,需用mysql DSN、显式指定charset=utf8mb4和ATTR_TIMEOUT=5,禁用持久连接,并确保账号权限、DNS解析及控制台白名单配置正确。

PHP
编写健壮的PHP代码,规避类型转换陷阱、数组怪癖及常见安全漏洞。
下载
PDO 是 PHP 7.1 连接 PolarDB 最稳妥的方式,不推荐用已废弃的
mysql_* 函数。PolarDB MySQL 版完全兼容 MySQL 协议,但连接细节稍有不同——尤其在 DNS 解析、超时控制和字符集上容易出错。
确认引擎类型再选驱动
PolarDB 不是单一产品,而是分版的:MySQL 版、PostgreSQL 版、Oracle 兼容版(实际走 PostgreSQL 协议)。PHP 连接前必须明确你用的是哪一版:
- PolarDB MySQL 版 → 必须用
PDO + mysql DSN,不能用 mysqli 的长连接模式(部分版本存在 handshake timeout)
- PolarDB PostgreSQL 版 → 用
PDO + pgsql DSN;若误用 mysql,会报 SQLSTATE[HY000] [2002] Connection refused,不是密码错,是协议不通
- Oracle 兼容版(PolarDB PostgreSQL 2.0+)→ 仍用
pgsql,但需注意:TO_DATE()、ROWNUM 等 Oracle 特有函数不可用,DDL 语法也受限
DSN 中 host 和 port 别硬编码
PolarDB 控制台显示的“公网地址”形如
xxx-polardb.mysql.polardb.rds.aliyuncs.com,端口未必是 3306:
- MySQL 版默认 3306,但某些地域或集群可能启用自定义端口(如 3307),务必以控制台「连接信息」页显示为准
- PostgreSQL 版常见端口是 5432,但也可能为 6432 或其他值,填错直接
Connection refused
- host 不要加
http:// 或 https:// 前缀;也不要用内网地址(如 vpc-xxx.mysql.polardb.rds.aliyuncs.com)从公网连,否则解析失败
- 如果 DNS 解析慢或失败,可临时改用 IP 地址(在控制台「连接信息」页点击「复制 IP」获取),但 IP 可能随维护变更,仅作调试用
账号权限与密码特殊字符问题
PolarDB 要求连接账号是控制台「账号管理」里创建的普通账号,且密码不能含 URL 敏感字符:
- 系统账号如
root、admin 无法通过 PHP 连接,会报 Access denied for user
- 密码含
@、/、:、? 会导致 PDO 解析 DSN 截断,例如 password=abc@123 会被当成 abc,后面全丢弃
- 正确写法是用
urlencode() 包裹密码:$pwd = urlencode('abc@123');,再拼进 DSN
- 账号必须已在「授权数据库」中显式赋予目标库的
SELECT、INSERT 等权限;只给 USAGE 会导致 Database not selected 错误
PHP 7.1 下必须显式设置 charset 和 timeout
PolarDB 默认字符集是
utf8mb4,但 PHP 7.1 的
PDO 不自动协商,不设会乱码或插入失败:
- DSN 后必须追加
;charset=utf8mb4,例如:mysql:host=xxx-polardb.mysql.polardb.rds.aliyuncs.com;port=3306;dbname=test;charset=utf8mb4
- 加上
PDO::ATTR_TIMEOUT => 5,否则网络抖动时请求卡住 30 秒才失败
- 禁用持久连接:
PDO::ATTR_PERSISTENT => false,PolarDB 的连接池机制与 PHP 的 persistent connection 冲突,易导致 MySQL server has gone away
- 别依赖
set_charset() 方法补救——它在某些 PolarDB 版本上无效,必须从 DSN 层面指定
PolarDB 的连接行为高度依赖控制台配置项,而不是 PHP 侧能绕过的。最常被忽略的是白名单没开、公网没启用、账号没授权这三处,错误现象看起来像 PHP 代码问题,其实根本连不到服务端。