Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

multiple mysqli objects overwrite each other

Tags:

php

mysqli

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?

like image 360
Marki Avatar asked Mar 02 '23 23:03

Marki


1 Answers

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.

like image 75
Dharman Avatar answered Mar 05 '23 16:03

Dharman