必须使用mysqli_client_ssl标志而非ssl_set(),因多数场景无需客户端证书;误用ssl_set()易触发“unknown ca”错误,正确方式是mysqli_init()后直接real_connect并传入mysqli_client_ssl标志。

MySQLi 连接必须用 MYSQLI_CLIENT_SSL,别调 ssl_set()
PHP 8.0 的 mysqli 扩展默认支持 SSL,但常见错误是误用 ssl_set() 强行指定客户端证书路径。只要 MySQL 服务端已正确配置 CA/Server 证书且用户启用了 REQUIRE SSL,客户端只需开启 SSL 标志即可,无需额外证书文件。
-
ssl_set()只在需要双向认证(即服务端也验证客户端证书)时才用;多数场景下它反而触发tlsv1 alert unknown ca错误 - 正确写法:
$conn = mysqli_init(); $conn->real_connect($host, $user, $pass, $db, $port, null, MYSQLI_CLIENT_SSL); - 若服务端未设
require_secure_transport = ON或用户没REQUIRE SSL权限,即使加了标志也走明文连接
pdo_mysql 要在 DSN 里写 ?sslmode=REQUIRED,不是 ssl_mode
pdo_mysql 不认 MySQL 服务端的 ssl_mode 变量(该变量已被弃用),必须通过 DSN 参数显式声明。漏掉或拼错参数名,连接会静默降级为非加密。
- 正确 DSN:
mysql:host=localhost;dbname=test;charset=utf8mb4;sslmode=REQUIRED - 错误写法:
ssl_mode=REQUIRED(无效)、ssl=true(不被识别) - 如果服务端 TLS 版本太低(如只支持 TLSv1.0),PHP 8.0 默认拒绝握手,需检查
SELECT @@GLOBAL.tls_version;
sqlsrv 连接 MSSQL 必须设 Encrypt=true 和 TrustServerCertificate=false
PHP 连接 SQL Server 时,Encrypt=true 是开关,但真正决定是否校验证书的是 TrustServerCertificate。设成 true 会跳过全部证书链验证——生产环境绝对不能这么干。
-
TrustServerCertificate=false要求系统 CA 库能验证服务器证书;若失败,先确认/etc/ssl/certs/ca-certificates.crt是否更新,或手动指定cafile - Windows 下若用 WAMP/XAMPP,CA bundle 常缺失,需手动下载
cacert.pem并在php.ini中设curl.cainfo和openssl.cafile - 连接后务必查
sys.dm_exec_connections确认encrypt_option为TRUE,光看连接成功不代表加密生效
证书验证失败时,先跑 openssl_get_cert_locations() 看路径
“certificate verify failed” 错误几乎都源于 PHP 找不到或读不了 CA bundle,而不是证书本身有问题。别急着改代码,先定位路径问题。
- 执行
php -r "print_r(openssl_get_cert_locations());",重点看default_cert_file值是否存在、可读、内容是否为有效 PEM 格式 - Linux/macOS 推荐用
curl -o /usr/local/share/ca-bundle.crt https://curl.se/ca/cacert.pem更新;macOS Homebrew 用户优先用/opt/homebrew/etc/openssl@3/cert.pem - CLI 和 FPM 的
php.ini可能不同,php --ini和phpinfo()要分别查,改完必须重启对应进程
require_secure_transport = ON 没开,或用户没 REQUIRE SSL,再怎么在 PHP 侧加标志也没用。验证时别只信连接成功,要查 information_schema.PROCESSLIST 里的 Ssl_cipher 字段是否非空。php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











