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

PHP8.0通过SSL连接Google Cloud SQL(MySQL8.0)失败求助

解决PHP连接Google Cloud SQL(MySQL8.0)的SSL连接问题

先上可直接测试的mysqli正确连接代码

先确保你用的是和Datagrip完全一致的证书文件(server-ca.pem、client-cert.pem、client-key.pem),并将代码中的路径、账号信息替换为你的实际内容:

<?php
$host = "你的Cloud SQL公网/私有IP";
$db_user = "你的数据库用户名";
$db_pass = "你的数据库密码";
$db_name = "要连接的数据库名";

// 证书文件路径,确保PHP进程能读取(比如放在项目ssl目录下)
$ssl_ca = __DIR__ . "/ssl/server-ca.pem";
$ssl_cert = __DIR__ . "/ssl/client-cert.pem";
$ssl_key = __DIR__ . "/ssl/client-key.pem";

// 初始化连接并配置SSL
$conn = mysqli_init();
// 注意参数顺序:key, cert, ca, capath, cipher
mysqli_ssl_set($conn, $ssl_key, $ssl_cert, $ssl_ca, null, null);

// 强制使用SSL连接
$connection_success = mysqli_real_connect(
    $conn,
    $host,
    $db_user,
    $db_pass,
    $db_name,
    3306,
    null,
    MYSQLI_CLIENT_SSL
);

if (!$connection_success) {
    die("连接失败: " . mysqli_connect_error());
}

echo "连接成功";
mysqli_close($conn);
?>

分步排查问题

1. 先解决「Access denied for user(using password: YES)」

  • 检查用户主机权限:登录Cloud SQL控制台,进入「用户」页面,确认你的数据库用户的「主机」列是%(允许所有IP),或者明确指定你的服务器公网IP。如果是localhost,远程连接会直接被拒绝。
  • 密码加密方式兼容:MySQL8.0默认用caching_sha2_password加密,旧版本PHP(<7.2)的mysqli扩展不支持该算法。解决办法二选一:
    • 在Cloud SQL中修改用户密码为mysql_native_password:执行ALTER USER '你的用户名'@'%' IDENTIFIED WITH mysql_native_password BY '你的密码';
    • 升级PHP到7.2及以上版本
  • 确认密码无转义问题:如果密码包含特殊字符(如&、#),直接写在代码里可能被解析错误,建议用单引号包裹密码字符串。

2. 解决「bad gateway」错误

这个错误本质是网络连通性或SSL配置失效:

  • 验证网络连通性:在你的服务器上执行telnet 你的Cloud SQL IP 3306,如果无法连接,检查:
    • Cloud SQL的「授权网络」是否添加了你的服务器公网IP
    • 服务器本地防火墙是否允许出站3306端口
    • 如果用私有网络连接,确认服务器和Cloud SQL在同一个VPC,路由配置正确
  • 检查证书权限和完整性:
    • 用ls -l查看证书文件权限,确保运行PHP的用户(如www-data)有读取权限(至少644)
    • 在PHP代码中添加var_dump(file_exists($ssl_ca), is_readable($ssl_ca));,确认证书路径正确且可读
    • 确保证书文件和Datagrip中使用的完全一致,不要修改文件名或内容

3. 如果你想尝试PDO(正确写法)

<?php
$dsn = "mysql:host=你的Cloud SQL IP;dbname=你的数据库名;port=3306;sslmode=VERIFY_IDENTITY";
$options = [
    PDO::MYSQL_ATTR_SSL_CA => __DIR__ . "/ssl/server-ca.pem",
    PDO::MYSQL_ATTR_SSL_CERT => __DIR__ . "/ssl/client-cert.pem",
    PDO::MYSQL_ATTR_SSL_KEY => __DIR__ . "/ssl/client-key.pem",
];

try {
    $pdo = new PDO($dsn, "你的用户名", "你的密码", $options);
    echo "PDO连接成功";
} catch (PDOException $e) {
    die("PDO连接失败: " . $e->getMessage());
}
?>

内容的提问来源于stack exchange,提问作者IT-Guy007

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 13:12:15