You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP Yii2远程MySQL SSL连接失败:控制台正常Web服务报1045错误

解决Yii2中控制台可连接远程SSL MySQL但Web服务无法连接的问题

针对你遇到的两种运行环境下的连接差异,以及PDO常量识别的问题,我整理了几个排查和解决方向:

一、先排查控制台与Web服务的核心差异

虽然你说phpInfo()配置一致,但以下细节很容易被忽略:

1. 运行用户与文件权限差异

控制台脚本是以当前登录用户身份执行的,而php yii serve启动的内置Web服务,默认是以PHP进程的运行用户(比如Linux下的www-data、Windows下的系统用户)来执行的。如果你的SSL证书文件(如ca.pem)权限设置为仅当前登录用户可读,Web服务用户就无法读取证书,进而导致SSL连接失败——MySQL有时会把SSL握手失败的错误伪装成"Access denied",这很容易误导排查方向。

解决方法:

  • 调整SSL证书文件的权限,让Web服务用户拥有读取权限:
    chmod o+r /path/to/your/ca.pem
    # 或者更安全的方式,将文件所属组改为Web服务用户组
    chgrp www-data /path/to/your/ca.pem
    chmod g+r /path/to/your/ca.pem
    

2. Yii配置文件的环境差异

Yii2的控制台和Web服务默认加载不同的配置文件:控制台用config/console.php,Web服务用config/web.php。你需要确认两个配置文件中,远程MySQL的连接参数(尤其是SSL相关配置)是否完全一致。

比如控制台配置里可能有:

'components' => [
    'remoteDb' => [
        'class' => 'yii\db\Connection',
        'dsn' => 'mysql:host=remote-mysql;dbname=your_db',
        'username' => 'userName',
        'password' => 'your_pass',
        'attributes' => [
            // SSL相关配置
            PDO::MYSQL_ATTR_SSL_CA => '/path/to/ca.pem',
        ],
    ],
],

要确保web.php里的remoteDb配置完全相同,没有遗漏SSL参数。

3. 出口IP差异

如果你的服务器有多个网络接口,控制台和Web服务的出口IP可能不同。远程MySQL的用户权限可能只允许控制台的IP访问,而Web服务的IP不在授权列表里,就会触发"Access denied"错误。

解决方法:

  • 查看Web服务的出口IP:在Web脚本中执行echo $_SERVER['SERVER_ADDR'];或者用curl ifconfig.me获取公网IP。
  • 登录远程MySQL,检查用户权限:
    SELECT host, user FROM mysql.user WHERE user='userName';
    
    如果Web服务的IP不在列表中,添加授权:
    GRANT ALL ON your_db.* TO 'userName'@'web-service-ip' IDENTIFIED BY 'your_pass' REQUIRE SSL;
    FLUSH PRIVILEGES;
    

二、解决PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT常量不存在的问题

你在CLI中能识别该常量,但Web环境中无法识别,大概率是PDO MySQL扩展版本差异或者命名空间干扰导致的。

1. 直接使用常量值替代

既然你已经通过php -r 'var_dump(PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT);'确认常量值为1014,可以直接在配置中用数值代替常量:

'attributes' => [
    1014 => false, // 替代PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT
    PDO::MYSQL_ATTR_SSL_CA => '/path/to/ca.pem',
    // 其他SSL参数
],

2. 验证Web环境的PDO扩展

在Web脚本中添加以下代码,确认PDO MySQL扩展的状态:

var_dump(extension_loaded('pdo_mysql'));
var_dump(phpversion('pdo_mysql'));

对比CLI下的输出,如果版本不一致,说明Web环境和CLI使用的是不同的PHP配置,需要调整Web服务器的PHP配置,确保加载的PDO MySQL扩展支持SSL常量。

三、额外调试步骤

如果以上方法都无效,可以用原生PHP代码在Web环境中直接测试连接,排除Yii框架的干扰:

// 用mysqli测试SSL连接
$conn = mysqli_init();
mysqli_ssl_set($conn, NULL, NULL, '/path/to/ca.pem', NULL, NULL);
if (!mysqli_real_connect($conn, 'remote-host', 'userName', 'password', 'dbname', 3306, NULL, MYSQLI_CLIENT_SSL)) {
    die('连接错误: ' . mysqli_connect_error());
}
echo '连接成功';
mysqli_close($conn);

如果这段代码在Web环境中也失败,说明问题出在PHP Web环境的SSL配置上,而非Yii框架。

内容的提问来源于stack exchange,提问作者viks1010

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 08:54:56