Andrea Casaccia
Andrea Casaccia

Reputation: 4971

Why does display_errors change the HTTP status code?

As pointed out in many other questions, turning display_errors to Off in php.ini makes the web server answer with status code 500 Internal server error instead of 200 OK when encountering a fatal error. I set up a simple test with an undefined function to explain the behaviour:

php.ini

display_errors = On

index.php

<?php test();

Gives:

Fatal error: Call to undefined function test()
in D:\xampp\htdocs\index.php on line 1

or just a blank page if i silence the function call like this:

<?php @test();

In both cases answer headers are as following:

HTTP/1.1 200 OK
Date: Tue, 10 Jul 2012 20:08:22 GMT
Server: Apache/2.2.21 (Win32) mod_ssl/2.2.21 OpenSSL/1.0.0e PHP/5.3.8 mod_perl/2.0.4 Perl/v5.10.1
X-Powered-By: PHP/5.3.8
Content-Length: 0
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/html

While changing php.ini to:

display_errors = Off

Causes:

HTTP/1.0 500 Internal Server Error
Date: Tue, 10 Jul 2012 20:10:35 GMT
Server: Apache/2.2.21 (Win32) mod_ssl/2.2.21 OpenSSL/1.0.0e PHP/5.3.8 mod_perl/2.0.4 Perl/v5.10.1
X-Powered-By: PHP/5.3.8
Content-Length: 0
Connection: close
Content-Type: text/html

Can anybody explain me the underlaying mechanism that makes the web server answer with 500 when display_errors is Off?

Upvotes: 9

Views: 4506

Answers (2)

Time Killer
Time Killer

Reputation: 846

I think this is a legacy issue from history. On older IE browsers, the HTML body is ignored when the status code is 500. Debugging is difficult due to the inability to view the errors shown in the body. Changing the status code to 200 is a compatibility for these old browsers.

This should help. bugs

if(1 == ini_get('display_errors')) {
  register_shutdown_function(function() {
    if ((error_get_last()['type']??0) == E_ERROR) {
        headers_sent() || http_response_code(500);
    }
  });
}

Upvotes: -2

Chris Trahey
Chris Trahey

Reputation: 18290

The reason is that with display_errors = On, you are essentially asking PHP to give you a decent HTTP response even when there are errors in your script. Think of it like an additional layer between your script and the response. It's no longer your script controlling the output, it's PHP.

When you turn this option on, you are in effect saying, "If there is an error, please still give me a valid HTTP response page (it may even include decent markup), since I will be looking at that instead of my logs."

With it set to Off, the HTTP response should be meaningless, and therefore a 500. With it On, a PHP error is anticipated, so the request on the whole is not 500, even though your script failed.

Upvotes: 9

Related Questions