1

When I kick the website I'm building over to my production server, I want the production server to show a custom .html page whenever the user tries to load a page with a PHP error on it.

On my in-home development server, I currently have the php.ini error values set to production values, so the browser only shows a "500 Server Error" page when I load a page I knowingly have syntax errors on. I tried using an .htaccess file with ErrorDocument 500 /500.html written in it to intercept that error. But it didn't work; the browser still showed me the default 500 page.

After a little Google-fu, I'm being led to believe that PHP syntax errors do not trigger a real 500 error, which is why my custom page won't load.

Is there a way to load a custom error page when the browser tries to load a page with a PHP syntax error on it?

I have carte blanche to do what I will with my in-home server, but I pay for hosting on my production server, so I'm limited to using PHP code and .htaccess files. I want to rig my in-home server so it uses pretty much the same rules as the production server when I migrate the site over. Their server logs all PHP errors to an error_log file when a bad page is loaded. I just want to make it so the end-user sees something a little more helpful if there are migration issues while migrating, but not see any detail about the syntax error itself.

1

PHP syntax errors do not trigger a real 500 error

No, it's certainly a "real 500 error", it's just that it's triggered by PHP and not Apache, which is why the Apache ErrorDocument does not get triggered. (In much the same way if your PHP script returns a 404 Not Found response, Apache doesn't step in and respond with the defined 404 ErrorDocument.)

PHP responds with a 500 Internal Server Error in the following scenario:

  • A fatal PHP error has occurred.
  • display_errors is "Off".
  • No output has been started (so the response body is otherwise empty). (If display_errors was "On" then you'd get output.)

The 500 response is really a last ditch attempt to let the client know an error occurred. If there is any output before the fatal error, then you'll get a regular 200 OK response.

PHP syntax errors (ie. fatal E_PARSE errors) are not trappable using a normal error handler. (Presumably you've already registered a custom error handler?) However, you can register a shutdown function in PHP that is always called at the end of your script, even after a fatal PHP error has occurred. In this shutdown function you can check the last error and "do something", eg. output a friendly response. There are a couple of prerequisites with this approach:

  • The shutdown function must be registered before the error is discovered.
  • The shutdown function can not be defined/registered in the same file as the error.

So, for example, you can do something like this:

In mypage.php:

<?php
function shutDownFunction() { 
    $error = error_get_last();
    if ($error && ($error['type'] == E_PARSE)) {
        // Call your error handler or something...
        echo 'A fatal parse error occured!';
    } 
}
register_shutdown_function('shutDownFunction');

// Include a file that contains a fatal parse error!
include 'fatal-parse-error.inc.php';

And in fatal-parse-error.inc.php you have a syntax error:

<?php
syntax error

I just want to make it so the end-user sees something a little more helpful if there are migration issues while migrating, but not see any detail about the syntax error itself.

However, do you really mean "PHP syntax errors"? And not trappable runtime errors like database connection problems etc? You really shouldn't be getting E_PARSE errors in a production environment, or at least this is an extreme edge case if you do.

If the "migration" is a big'un, then maybe you should be restricting access and serving a temporary "503 Service Unavailable" for all users except a select few?

Reference:

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.