If I create two parallel connections to two servers:
$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;
}
If gw03 is available but gw04 is not, the following is the result
Failed to connect to gw03: (2002) No route to host
Failed to connect to gw04: (2002) No route to host
The failure to connect to $gw04 seems to overwrite $gw03. Aren't $gw03 and $gw04 separate objects? What's going on here?
Unfortunately, mysqli suffers from bad design. The properties connect_errno
and connect_error
are not really properties. They are just shortcuts to global variables. When the second connection fails the global variable is overwritten internally.
This is a very good reason to stop checking for mysqli errors manually. When an error happens your code should throw an error instead of a warning or failing silently. This error should be properly handled by your application and logged in a secure place on the server. Don't try-catch
or echo
the error message to the user!
To enable mysqli error reporting you should add the following line before any new mysqli()/mysqli_connect()
:
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
This setting will tell mysqli to throw an exception as soon as an error is encountered. No more manual checking and no more problems with global variables overwriting themselves.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With