php 8 连接 mysql ssl 握手失败,主因是客户端未正确传递证书路径、验证模式不匹配或 pdo/mysqli 初始化顺序错误;须确认服务端 have_ssl=yes、ssl_mode≥preferred、ssl_cipher非空,并严格按序配置pdo(verify_identity需匹配域名)或mysqli(ssl_set必须在real_connect前)。

PHP 8 连接 MySQL 数据库时 SSL 握手失败,常见于服务端已启用 SSL 但客户端未正确传递证书路径、验证模式不匹配或 PDO/MySQLi 初始化顺序错误,导致连接被拒绝或静默中断。
确认 MySQL 服务端 SSL 状态
登录 MySQL 命令行,执行以下三条命令:
【必须全部返回 YES 或非空值】:SHOW VARIABLES LIKE 'have_ssl'; → 应返回 YES;SHOW VARIABLES LIKE 'ssl_mode'; → 至少为 PREFERRED;SHOW STATUS LIKE 'Ssl_cipher'; → 若为空,说明当前连接未走 SSL,服务端可能未真正启用加密通道。
若第一条返回 DISABLED 或 NO,说明 MySQL 编译时未启用 SSL 支持,需重装带 SSL 的 MySQL 或修改 my.cnf 启用 ssl-ca/ssl-cert/ssl-key 并重启服务。
PDO 方式启用 SSL(推荐)
方法一:仅启用加密(开发环境快速验证)
在 new PDO() 第四个参数中传入数组,设置 PDO::MYSQL_ATTR_SSL_MODE 为 PDO::MYSQL_ATTR_SSL_MODE_REQUIRED;【不可省略此选项,否则 PHP 8.1+ 默认禁用 SSL】。
方法二:严格校验证书(生产环境必需)
第一步:确保 CA 证书(ca.pem)、客户端证书(client-cert.pem)和私钥(client-key.pem)三者均存在且可读;
第二步:PDO 构造时传入完整选项:
$options = [
PDO::MYSQL_ATTR_SSL_MODE => PDO::MYSQL_ATTR_SSL_MODE_VERIFY_IDENTITY,
PDO::MYSQL_ATTR_SSL_CA => '/etc/mysql/ssl/ca.pem',
PDO::MYSQL_ATTR_SSL_CERT => '/etc/mysql/ssl/client-cert.pem',
PDO::MYSQL_ATTR_SSL_KEY => '/etc/mysql/ssl/client-key.pem'
];
第三步:连接字符串中 host 不可写 127.0.0.1,必须使用域名或 localhost —— 【否则 VERIFY_IDENTITY 模式下会因 CN/SAN 不匹配直接失败】。
MySQLi 方式启用 SSL
对象方式必须严格按顺序执行:
① 实例化 mysqli 对象(不传参);
② 立即调用 $mysqli->ssl_set(),传入 client-key、client-cert、ca 三个 PEM 路径(第四个参数为密码,无则 null);
③ 执行 $mysqli->real_connect($host, $user, $pass, $db, $port, $socket, $flags) —— 【ssl_set() 必须在 real_connect() 之前,且不能用 connect() 简写】;
过程方式同理:先 mysqli_init(),再 mysqli_ssl_set(),最后 mysqli_real_connect()。
这一步操作起来很简单,直接把文件路径填对就行,但顺序错一步就会报 “SSL connection error” 且无具体原因提示。
排查 OpenSSL 与证书链兼容性
PHP 8 使用系统 OpenSSL 库,若服务器 OpenSSL 版本低于 1.1.1(如 CentOS 7 默认为 1.0.2),会导致 TLSv1.3 不可用、证书链解析失败;
运行 openssl version -a 验证版本,低于 1.1.1 则升级 OpenSSL 或降级 SSL 模式为 REQUIRED(跳过证书校验);
检查 ca.pem 是否包含完整信任链:用 cat ca.pem | grep "BEGIN CERTIFICATE" 统计行数,少于 2 行说明中间证书缺失,需合并 root + intermediate。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











