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及以上版本
- 在Cloud SQL中修改用户密码为
- 确认密码无转义问题:如果密码包含特殊字符(如
&、#),直接写在代码里可能被解析错误,建议用单引号包裹密码字符串。
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
相关产品推荐
相关产品推荐

