Should we ever check for mysqli_connect() errors m

2020-01-22 12:12发布

问题:

The PHP manual for mysqli_connect() suggests checking for the return value and displaying the error messages on the screen.

$link = mysqli_connect("127.0.0.1", "my_user", "my_password", "my_db");
if (!$link) {
    echo "Error: Unable to connect to MySQL." . PHP_EOL;
    echo "Debugging errno: " . mysqli_connect_errno() . PHP_EOL;
    echo "Debugging error: " . mysqli_connect_error() . PHP_EOL;
    exit;
}

Similarly for OOP-style constructor this is suggested:

$mysqli = new mysqli('localhost', 'my_user', 'my_password', 'my_db');
if ($mysqli->connect_error) {
    die('Connect Error (' . $mysqli->connect_errno . ') '
            . $mysqli->connect_error);
}

Some users on Stack Overflow even used code with mysqli_error($conn) such as this:

$conn = mysqli_connect('localhost', 'a', 'a');
if (!$con) {
    die('Could not connect: ' . mysqli_error($conn));
}

However, in the past few weeks I have been asking myself a question, why would I need to do that? The output of the first example is:

Warning: mysqli_connect(): (HY000/1045): Access denied for user 'my_user'@'localhost' (using password: YES) in C:\xampp\...\mysqli.php on line 4

Error: Unable to connect to MySQL. Debugging errno: 1045 Debugging error: Access denied for user 'my_user'@'localhost' (using password: YES)

As you can see the error message is displayed twice! The manual "debugging" actually provides less information.

Should we ever manually check for connection errors? Would we ever get more information this way than from the automatic warning? Is this the recommended practice?

回答1:

Never display connection errors manually!

MySQLi will generate a warning if it is unable to open the connection to MySQL. This warning tells you all you need to know including the error code, error message, and the place in the code where it happened. Checking for the error manually will not give you any more information.

If you can't see the warning and your connection cannot be created, it might mean that your PHP is not configured to show them. In that case, you must check your server logs for the error_log file. If you do not know where that is, use phpinfo() to get that information and search for error_log. It will tell you where the error log file is located.

If there is no warning in the error logs, it could mean that your PHP has error reporting silenced (either completely or just warnings). Check your PHP configuration.
In the production environment these settings should be maintained:

  • error_reporting must be E_ALL
  • log_errors must be On
  • display_errors must be Off

In the development environment these settings should be maintained:

  • error_reporting must be E_ALL
  • log_errors must be On
  • display_errors must be On

As you can see in the error message your database username and password has been revealed to the end user. These are sensitive information which you do not want to show anyone. In fact a normal user would not understand this cryptic message. This is why display_errors must always be switched off in the production environment. Logging the errors on the server is safe.

Warnings vs. Exceptions

Warnings do not stop the script. If a warning is emitted the script will keep on executing until it encounters a fatal error. In most cases you would want to throw an exception to stop the script. Do not use die/exit! If mysqli connection cannot be made, an exception should be thrown and if it is unhandled it will bubble up and stop the script with a fatal error. You can configure mysqli to throw exceptions automatically. This is very useful, because all mysqli functions can fail for many reasons and they will not inform you about any problems unless you check for errors manually every single one of them. Use the following line before opening connection:

mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$mysqli = new mysqli('localhost', 'my_user', 'my_password', 'my_db');

Do not catch the exceptions unless you really know what to do with them! One possible use case is described in How to connect properly using mysqli

Can mysqli_error() show any connection-related problems?

No. mysqli_error($conn) expects that the mysqli connection was successful. $conn must be a valid mysqli connection otherwise you would get this error message:

Warning: mysqli_error(): Couldn't fetch mysqli in C:\...

Neither $conn->error nor mysqli_error($conn) can display any connection related errors!