ThinkPHP 6 连接 MySQL 启用 SSL 必须在 config/database.php 的 params 数组中严格使用 PDO 常量(如 PDO::MYSQL_ATTR_SSL_CA)传入证书绝对路径,拼接 DSN、写 sslmode 或动态设置均无效;漏配 CA 或路径错误将导致 SQLSTATE[HY000] [2002] 错误。

ThinkPHP 6 连接 MySQL 启用 SSL 加密,**必须通过 config/database.php 中的 params 数组显式传入 PDO 常量参数**,其他任何方式(如拼接 DSN、写 sslmode、在模型里动态设置)都无效。
SSL 参数只能填在 params 数组里
ThinkPHP 的 MySQL 连接器在构建 DSN 时会过滤掉所有非标准字段,?ssl_mode=REQUIRED 或 &ssl_ca=/path 这类 URL 参数会被直接丢弃。真正起作用的只有 params 下的 PDO 常量键名。
-
params必须是数组,不能是字符串或空值 - 键名必须是完整常量,如
PDO::MYSQL_ATTR_SSL_CA,写成'mysql_attr_ssl_ca'或小写都会被忽略 - 值必须是服务器本地绝对路径(如
/etc/mysql/ssl/ca.pem),相对路径(./certs/ca.pem)或 HTTP URL 会失败 - 若只配了
CERT和KEY却漏掉CA,PDO 会报SQLSTATE[HY000] [2002] SSL connection error,即使服务端实际支持 SSL
自签名证书场景下怎么设 PDO::MYSQL_ATTR_SSL_MODE
内网或测试环境常用自签名证书,此时不能用 PDO::MYSQL_ATTR_SSL_MODE_VERIFY_IDENTITY——它会校验域名,而自签证书通常没匹配域名,连接直接拒绝。
- 最常用且兼容性最好的是
PDO::MYSQL_ATTR_SSL_MODE_REQUIRED:只加密,不校验证书 - 若需校验 CA(比如你有自己的根 CA),用
PDO::MYSQL_ATTR_SSL_MODE_VERIFY_CA,但必须确保PDO::MYSQL_ATTR_SSL_CA指向包含该根证书的 PEM 文件 -
PDO::MYSQL_ATTR_SSL_MODE_VERIFY_IDENTITY仅适用于由公共 CA 签发、且域名完全匹配的服务端证书 - 别碰
PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT => false,这个选项在新版 libmysqlclient 中已被废弃,可能静默失效或触发警告
证书校验不生效?缺这个参数
即使你配齐了 CA、CERT、KEY,默认情况下 PDO **不会主动校验服务端证书**。ThinkPHP 不封装这个开关,必须手动加:
立即学习“PHP免费学习笔记(深入)”;
- 在
params中加入PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT => true - 这个参数在 ThinkPHP 5.1 中被硬编码过滤,只在 TP6+ 有效
- Windows 下路径含反斜杠(
C:certsca.pem)会导致读取失败,建议统一用正斜杠或str_replace('\', '/', $path)预处理 - 临时验证是否启用:把 CA 文件内容删几行再试,如果连接仍成功,说明校验根本没走
最容易被忽略的是文件权限和 SELinux 上下文——PHP 进程(如 www-data 或 nginx 用户)必须对证书文件有读取权限,且 SELinux 策略未阻止 httpd_t 访问 cert_t 类型文件。抓包验证是否真走 TLS 是最可靠的判断方式,光看连接成功不等于加密生效。



















