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

特定场景下PHP无法解析MySQL容器名称的连接异常问题

解决mysqli连接的两个常见错误

咱们先把你遇到的两个问题拆开来看,其实都是因为对mysqli的连接逻辑理解有偏差导致的:

第一个错误:主机名解析失败(getaddrinfo failed)

Warning: mysqli::real_connect(): php_network_getaddresses: getaddrinfo failed: Name or service not known

这个错误的核心原因是:mysqli并不支持PDO风格的mysql://username:password@db_hostname/dbname格式DSN字符串。如果你直接把这个DSN当作主机名参数传给mysqli的连接方法,它会把整个字符串当成主机名去尝试解析,自然找不到对应的网络地址,就抛出了这个错误。

第二个错误:空用户权限被拒(Access denied)

Warning: mysqli::real_connect(): (HY000/1045): Access denied for user ''@'172.21.0.3' (using password:

你手动调用mysqli::real_connect("db_hostname")时,只传递了主机名参数,没有传入用户名和密码。mysqli在这种情况下会默认使用空用户名去连接数据库,而你的数据库服务器显然没有授权空用户从172.21.0.3这个IP访问,所以触发了1045权限错误。

正确的解决方案:解析DSN后连接

如果你的配置里只能用这种PDO风格的DSN,那我们可以手动解析DSN,提取出各个连接参数后再传给mysqli:

// 你的原始DSN字符串
$dsn = 'mysql://username:password@db_hostname/dbname';

// 用parse_url解析DSN,拆分出各个部分
$dsnParts = parse_url($dsn);

// 提取必要的连接参数
$dbUser = $dsnParts['user'];
$dbPass = $dsnParts['pass'];
$dbHost = $dsnParts['host'];
// 路径部分开头的/要去掉,剩下的就是数据库名
$dbName = ltrim($dsnParts['path'], '/');

// 初始化mysqli并建立连接
$mysqli = new mysqli();
$connectionSuccess = $mysqli->real_connect(
    $dbHost,
    $dbUser,
    $dbPass,
    $dbName
);

// 检查连接结果
if (!$connectionSuccess) {
    die("连接失败: " . $mysqli->connect_error);
}

额外注意事项

  • 确认db_hostname在你的环境中可以正常解析:比如在Docker容器环境中,要确保数据库容器和应用容器在同一个网络,且容器名可以被正确解析。
  • 确认数据库用户的权限范围:比如如果应用容器的IP是172.21.0.3,要确保数据库用户被授权从172.21.0.%或者%(任意IP)访问,授权语句类似:GRANT ALL ON dbname.* TO 'username'@'172.21.0.%' IDENTIFIED BY 'password';

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 10:21:47