如果我创建到两台服务器的两个并行连接:
$gw03 = new mysqli('gw03.example', 'user', 'pass', 'db');
$gw04 = new mysqli('gw04.example', 'user', 'pass', 'db');
if (!$gw03->connect_errno) {
...
} else if (!$gw04->connect_errno) {
...
} else {
echo "Failed to connect to gw03: (" . $gw03->connect_errno . ") " . $gw03->connect_error . PHP_EOL;
echo "Failed to connect to gw04: (" . $gw04->connect_errno . ") " . $gw04->connect_error . PHP_EOL;
}
Run Code Online (Sandbox Code Playgroud)
如果 gw03 可用但 gw04 不可用,则结果如下
Failed to connect to gw03: (2002) No route to host
Failed to connect to gw04: (2002) No route to host
Run Code Online (Sandbox Code Playgroud)
无法连接到 $gw04 似乎覆盖了 $gw03。$gw03 和 $gw04 不是独立的对象吗?这里发生了什么?
不幸的是,mysqli 的设计很糟糕。属性connect_errno和connect_error不是真正的属性。它们只是全局变量的捷径。当第二个连接失败时,全局变量在内部被覆盖。
这是停止手动检查 mysqli 错误的一个很好的理由。当发生错误时,您的代码应该抛出错误而不是警告或静默失败。此错误应由您的应用程序正确处理并记录在服务器上的安全位置。不要try-catch或echo错误信息给用户!
要启用 mysqli 错误报告,您应该在任何之前添加以下行new mysqli()/mysqli_connect():
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
Run Code Online (Sandbox Code Playgroud)
此设置将告诉 mysqli 在遇到错误时立即抛出异常。不再需要手动检查,也不再有全局变量覆盖自身的问题。