PHP连接启用TLS/SSL的MySQL需配置客户端证书、CA文件等,先确认服务端SHOW VARIABLES LIKE 'have_ssl'为YES,mysqli用ssl_set()(绝对路径)、PDO在DSN中指定sslca等参数(PHP 7.2+),并验证Ssl_cipher状态。
PHP 连接加密的 MySQL(即启用了 TLS/SSL 的 MySQL 服务器)不需要“解密”——你不是在解密数据库,而是在建立带证书验证的安全连接。关键在于配置 PHP 的 mysqli 或 PDO 扩展正确加载客户端证书、密钥和 CA 证书。
不先确认服务端状态,客户端配再全也连不上。登录 MySQL 执行:
SHOW VARIABLES LIKE 'have_ssl';
返回 YES 才表示服务端支持 SSL;再查:
SHOW VARIABLES LIKE 'ssl%';
重点关注 ssl_ca、ssl_cert、ssl_key 对应的路径是否非空且可读。
have_ssl 是 DISABLED,说明 MySQL 启动时没加 --ssl-mode=REQUIRED 或相关参数,客户端强制 SSL 会失败SSL connection is required
mysqli 不通过 DSN 配置 SSL,而是调用 mysqli::ssl_set() 方法设置证书路径,且必须在 mysqli::real_connect() 之前调用。
mysqli::ssl_set() 四个参数顺序固定:$key_file、$cert_file、$ca_file、$capath、$cipher;前三个为必需,后两个可传 null
$ca_file;若还需双向认证(服务端验证客户端),才需 $key_file 和 $cert_file
var_dump($mysqli->get_client_info()); 和 var_dump($mysqli->query("SHOW STATUS LIKE 'Ssl_cipher'")->fetch_row()); 确认实际启用了加密PDO 在 DSN 中通过 sslmode、sslcert、sslkey、sslca 等属性传参,但注意:这些参数名**不是标准 PDO 属性**,而是 MySQL 驱动(pdo_mysql)特有的

mysql:host=localhost;port=3306;dbname=test;charset=utf8mb4;sslmode=REQUIRED;sslca=/path/to/ca.pem;sslcert=/path/to/client-cert.pem;sslkey=/path/to/client-key.pem
sslca 等参数,会静默忽略,导致连接看似成功实则未加密new PDO(...) 后捕获异常,并检查 $pdo->getAttribute(PDO::ATTR_SSL_MODE) 返回值(如 PDO::SSL_MODE_REQUIRED)报错 SSL connection error: protocol version mismatch 或 Unable to set certificate verify locations 很可能不是代码问题,而是环境配置偏差。
php -m | grep openssl 应输出 openssl),或 OpenSSL 版本太低(如 PHP 用 OpenSSL 1.0.x,MySQL 服务端要求 1.2+)-----BEGIN CERTIFICATE----- 段落,漏掉末尾的 -----END CERTIFICATE-----
mysqli_connect() 的第 5–7 个参数是 SSL 设置——它们是旧版 MySQL 协议的超时/重连参数,与 SSL 无关真正难的不是写几行代码,而是让 PHP、OpenSSL、MySQL 三者在证书链、协议版本、文件权限上对齐。调试时优先用 mysql --ssl-ca=... --ssl-cert=... --ssl-key=... 命令行验证证书可用性,再迁移到 PHP。