PDO连接MySQL 8.0需满足:pdo_mysql底层Client API版本≥8.0.x,DSN显式指定charset=utf8mb4并禁用SSL,开启PDO::ERRMODE_EXCEPTION错误模式,且MySQL用户认证插件须为mysql_native_password。

pdo_mysql底层客户端版本必须 ≥ 8.0.x
PHP 8.2 自带 pdo_mysql 扩展,但默认链接的客户端库(mysqlnd 或 libmysqlclient)可能仍是 5.7 或 7.x 版本,导致无法握手 MySQL 8.0 的 caching_sha2_password 认证插件——错误信息通常是 The server requested authentication method unknown to the client。
关键不是 PHP 版本够不够新,而是驱动实际编译时绑定的 client API 版本:
- 运行
php -i | grep -A5 "pdo_mysql",找Client API version行,必须是8.0.x(如8.0.33),5.7.34或mysqlnd 7.4.33都不支持 - Ubuntu/Debian 用户直接
sudo apt install php-mysql通常能拉到新版 mysqlnd;CentOS/RHEL 建议启用 Remi 仓库再装php-mysqlnd - Windows 下用 phpEnv,要确认
php_pdo_mysql.dll来自 PHP 8.2 官方包,而非旧版残留文件
DSN 必须显式声明 charset=utf8mb4 且禁用 SSL 校验
MySQL 8.0 默认字符集是 utf8mb4_0900_ai_ci,PDO 初始化时不指定 charset,连接会 fallback 到 latin1 或 utf8(即 utf8mb3),后续插入 emoji 或生僻汉字直接报错或乱码。
云数据库(如阿里云 RDS)常强制 SSL,但 PHP 8.2 默认没配证书路径,连接会静默失败:
立即学习“PHP免费学习笔记(深入)”;
- DSN 示例:
mysql:host=127.0.0.1;port=3306;dbname=test;charset=utf8mb4——localhost在 Windows 下易触发命名管道冲突,务必用127.0.0.1 - 第四个参数数组中必须包含:
PDO::MYSQL_ATTR_SSL_CA => null(或PDO::MYSQL_ATTR_SSL_MODE => PDO::SSL_DISABLED) - 不要依赖
SET NAMES utf8mb4替代 DSN 中的charset,PDO 连接建立前字符集就该确定
必须开启 PDO::ERRMODE_EXCEPTION 否则连接失败不报错
很多人写 new PDO($dsn, $user, $pass) 发现返回 false 却没任何提示,代码静默挂掉——因为 PDO 默认错误模式是 PDO::ERRMODE_SILENT,只设 $pdo->errorCode(),不抛异常。
尤其在调试阶段,没开异常模式等于把错误藏进黑盒:
- 必须传入第四个参数:
[PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION] - 搭配 try/catch 才能捕获真实错误,比如
SQLSTATE[HY000] [2054]或Connection refused - 顺手加上
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC可省去每次调fetch(PDO::FETCH_ASSOC)
MySQL 用户认证插件必须改 mysql_native_password(临时解法)
即使客户端版本达标,若 MySQL 用户仍用 caching_sha2_password,部分环境(尤其是 phpEnv、XAMPP、Docker 默认镜像)仍会握手失败。这不是 bug,是插件能力未被完全激活的表现。
最稳的临时解法是服务端降级认证方式:
- 登录 MySQL:
mysql -h 127.0.0.1 -u root -proot(注意:phpEnv 默认 root 密码是root,不是空) - 执行:
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'root'; - 再执行:
FLUSH PRIVILEGES; - 验证:
SELECT user, host, plugin FROM mysql.user WHERE user = 'root';,确认plugin列为mysql_native_password
这个操作只影响指定用户,不影响其他 host 的账号,也不动全局配置,适合本地开发快速验证。真正上线时,应确保客户端驱动和 MySQL 服务端都稳定支持 caching_sha2_password,而不是长期依赖降级方案。



















