最直接有效的修复方式是禁用客户端 SSL,仅限开发环境;需在 Hyperf 的 database.php 中配置 PDO::MYSQL_ATTR_SSL_MODE => PDO::MYSQL_ATTR_SSL_MODE_DISABLED,并移除所有其他 SSL 相关选项。

Hyperf 连接 MySQL 报 SSL 连接错误,最直接有效的修复方式是禁用客户端 SSL,但必须明确:这不是“修 bug”,而是主动关闭安全校验——仅限开发环境。
为什么 mysql 命令能连上,Hyperf 却报 SSL connection error: unknown error number
MySQL 8.x 默认启用 SSL,但命令行客户端(mysql)在未显式指定 SSL 参数时会自动降级为非加密连接;而 Hyperf 底层的 PDO 或 mysqli 扩展在某些配置下会强制尝试 SSL 握手,一旦服务端没配证书或客户端不提供验证路径,就卡在 unknown error number ——这其实是 OpenSSL 底层没抛出具体错误码的兜底提示。
- 检查服务端是否真启用了 SSL:
SHOW VARIABLES LIKE 'have_ssl';,若返回DISABLED或NO,说明服务端压根没开 SSL,客户端却在瞎试 - Hyperf 的
database.php配置中若写了'options' => [PDO::MYSQL_ATTR_SSL_CA => '/path']等字段,但路径无效或文件为空,也会触发该错误 - PHP 的
mysqli扩展若启用了MYSQLI_CLIENT_SSL_DONT_VERIFY_SERVER_CERT标志(旧写法),反而会干扰握手流程,导致静默失败
在 database.php 中禁用 SSL 的正确写法
Hyperf 使用 PDO 连接 MySQL,禁用 SSL 要落在 DSN 或 PDO options 里,不是改全局 PHP 设置。
面向 CRM 系统的 MySQL 8 数据库模式设计。当用户需要为客户关系管理(CRM)系统设计、评审、优化或生成数据库模式时,应使用此项技能。
- DSN 中加
?sslmode=disabled(仅部分驱动支持,不通用) - 更可靠的是在
'options'数组中传入PDO::MYSQL_ATTR_SSL_MODE => PDO::MYSQL_ATTR_SSL_MODE_DISABLED - **必须同时移除所有 SSL 相关选项**:删掉
PDO::MYSQL_ATTR_SSL_CA、PDO::MYSQL_ATTR_SSL_CERT、PDO::MYSQL_ATTR_SSL_KEY等键,否则 PDO 会优先尝试 SSL - 示例配置片段:
'mysql' => [
'driver' => 'mysql',
'host' => env('DB_HOST', '127.0.0.1'),
'port' => env('DB_PORT', 3306'),
'database' => env('DB_DATABASE', 'hyperf'),
'username' => env('DB_USERNAME', 'root'),
'password' => env('DB_PASSWORD', ''),
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
'prefix' => '',
'strict' => true,
'options' => [
PDO::ATTR_CASE => PDO::CASE_NATURAL,
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_EMULATE_PREPARES => false,
PDO::MYSQL_ATTR_SSL_MODE => PDO::MYSQL_ATTR_SSL_MODE_DISABLED, // ? 关键
// 删掉下面这几行(如果存在)
// PDO::MYSQL_ATTR_SSL_CA => '/xxx/ca.pem',
// PDO::MYSQL_ATTR_SSL_CERT => '/xxx/client-cert.pem',
// PDO::MYSQL_ATTR_SSL_KEY => '/xxx/client-key.pem',
],
],
为什么不用 skip_ssl = 1 改 MySQL 配置?
你可以在 MySQL 的 my.cnf 里加 skip_ssl 并重启服务,但这会影响所有客户端,且在容器化或云数据库(如阿里云 RDS、AWS RDS)中根本不可行——你没有权限改服务端配置。Hyperf 作为客户端,应该控制自己的行为,而不是倒逼服务端妥协。
- 本地开发用 Docker 启 MySQL?直接在
docker run命令里加--ssl-mode=DISABLED不生效,因为那是 mysql client 的参数,不是 mysqld 的 - 云数据库强制要求 SSL?那就不能禁用,得走证书路线:用
setCaBundle()(注意是 PEM 格式,不是 .p12)、配对 SAN 域名、确保 PHP curl 支持 openssl - Hyperf worker 进程用户(如 www-data)若对证书文件无读权限,
file_get_contents失败会静默 fallback 到 SSL 错误,而非报 “permission denied”
真正麻烦的从来不是“怎么关 SSL”,而是关了之后忘了它本该开着——尤其当代码从 dev 分支合到 prod 时,database.php 里那行 PDO::MYSQL_ATTR_SSL_MODE_DISABLED 很容易被带过去。生产环境一旦漏掉证书配置又关了 SSL,等于裸奔。

















