Why cannot the PHP hide the error message thrown by the MySQL connection?

It seems you are using some outdated tutorial, that offers incorrect approach at reporting errors: a code that tries to detect the connection error manually and output something on its own. But your code shouldn’t be doing anything like that. Mysqli can report errors automatically and database errors are no different from other errors, and therefore do not require any special treatment.

Let’s answer your question step by step:

How to detect a connection error

In the ancient times, some 10 years ago, PHP used mysql extension to talk to MySQL database, which was unable to handle errors automatically, and every database operation had to be checked for errors manually. That’s where this if (!$conn) { stuff is coming from. But this library is long gone, and PHP got a new one, mysqli. Which has the ability to raise errors automatically, just like any other command in PHP, include or header() for example. You aren’t checking every include or header() result manually, are you? So you shouldn’t with mysqli.

As you can see, mysqli_connect() produces the error automatically, just like any other function. So there must be no if (!$conn) { part in your code. Neither on connect, nor with query() or any other mysqli function.

In a nutshell: you don’t need any code to detect database errors. They are regular errors now. And, if you think of it, not only database errors must be hidden. Any other error, like “Headers already sent” or “No such file or directory” must be hidden from a site user as well.

So the problem is more generic now:

How to hide all error messages from a site user

To hide error messages from a site user, you must use a configuration option that is intended exactly for this: display errors. While set to 0 it will prevent PHP from displaying any error occurred. It’s best to be set in php.ini but in case you don’t have a control over PHP configuration, at least you can set it right in the PHP code:

ini_set('display_errors', 0);

The best part of it, this is just a single place where it’s set. So, on your local PC or on a test server you can set it to 1 and watch all errors online. Again, without any changes in the code: as you can see, mysqli already provided a detailed error message, without that if (!$conn) { stuff! But on a live server, display errors must be set to 0, so not a single error message leaks to the user, while log_errors must be set yo 1. That’s a simple rule which is, sadly, seldom mentioned in the books or tutorials. By the way, I’d recommend PHP&MySQL book by Jon Duckett, where this approach is explained in detail.

Connection credentials

Even when credentials are not displayed, some people feel uncomfortable when sensitive information even gets logged. There are several ways to prevent this, refer to this answer for the details

So the only question left is “how to show the user the critical error message?”.

How to display a nice error page to a site user

Simply configure an error handler. Here is one from my article on PHP error reporting:

set_exception_handler(function ($e)
{
    error_log($e);
    http_response_code(500);
    if (ini_get('display_errors')) {
        echo $e;
    } else {
        echo "<h1>500 Internal Server Error</h1>
              An internal server error has been occurred.<br>
              Please try again later.";
    }
});

depends on the display_errors value, it will either display the error itself, or just a generic message.

Note that it “gives an HTTP 500 error” which, contrary to your request, is what actually must be done. When your page cannot provide the actual content due to server error, it must respond with 5xx HTTP code.

Leave a Comment