PHP 7.4 不能直接用 mysqli 或 pdo_mysql 连接 OceanBase,因认证插件不兼容:OceanBase 4.x 默认未完整支持 caching_sha2_password,而 PHP 7.4 默认协商该插件,导致报错“Authentication plugin 'caching_sha2_password' cannot be loaded”;需服务端降级为 mysql_native_password 并配合 PDO DSN 显式配置连接参数。

PHP7.4能否直接用mysqli或pdo_mysql连接OceanBase
不能。OceanBase 4.x 默认兼容 MySQL 协议,但其认证方式(尤其是 mysql_native_password)在 PHP7.4 的 mysqli 和 pdo_mysql 扩展中存在兼容性问题:PHP7.4 默认启用 caching_sha2_password 认证协商,而 OceanBase 早期版本(如 4.0.0~4.2.x)未完整支持该插件,连接时会报错 Authentication plugin 'caching_sha2_password' cannot be loaded 或直接拒绝连接。
必须改用 PDO + MySQLi 兼容模式 + 显式指定认证插件
实际可行路径是:使用 PDO(非 pdo_mysql,而是通过 mysql:host=... DSN),并强制服务端降级为 mysql_native_password 认证。前提是 OceanBase 已配置允许该插件(需 DBA 在租户级执行):
ALTER USER 'your_user'@'%' IDENTIFIED WITH mysql_native_password BY 'your_pass';
PHP 连接代码示例如下:
$dsn = "mysql:host=127.0.0.1;port=2883;dbname=test; charset=utf8mb4";
$options = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::MYSQL_ATTR_SSL_CA => '/path/to/ca.pem', // 如启用 SSL
PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8mb4",
];
try {
$pdo = new PDO($dsn, 'root', 'password', $options);
} catch (PDOException $e) {
echo $e->getMessage(); // 常见错误:SQLSTATE[HY000] [1045] Access denied
}- 端口必须是 OceanBase 的 MySQL 兼容端口(默认
2883,不是2881) -
charset=utf8mb4必须显式声明,否则中文可能乱码 - 若 OceanBase 启用了白名单或资源隔离(如
obproxy中转),需确认 IP 和租户名是否匹配
连接失败时优先排查的三个配置点
OceanBase 不是 MySQL,很多“理所当然”的配置在这里会失效:
立即学习“PHP免费学习笔记(深入)”;
- 检查
obclient -h127.0.0.1 -P2883 -u root@sys#obdemo -p能否连通——这是验证网络和账号权限的第一步 - 确认用户所属租户是否已开启 MySQL 模式:
SELECT * FROM oceanbase.__all_virtual_tenant WHERE tenant_name = 'your_tenant';中default_collation应为utf8mb4_general_ci,且mode为MYSQL - PHP 的
openssl扩展必须启用(即使不用 SSL,PDO 内部初始化也依赖它),运行php -m | grep openssl验证
不推荐用 mysqli_connect() 直连的原因
mysqli_connect() 无法传递认证插件参数,且对 connect_timeout、read_timeout 等底层 socket 控制粒度太粗。OceanBase 在高负载或跨机房场景下容易触发连接中断,表现为 MySQL server has gone away 或 Lost connection to MySQL server during query。PDO 支持更细粒度的重连控制(如配合 PDO::ATTR_EMULATE_PREPARES 和异常捕获重试),实测稳定性明显更高。
真正麻烦的不是写几行代码,而是 OceanBase 租户级配置、OBProxy 路由规则、以及 PHP 客户端对协议细节的隐式假设——这些地方一旦出错,报错信息几乎不提示真实原因。



















