I use PHP 5.2.9.
To see/log errors, at the beggining of my script I have:
error_reporting(E_ALL | E_STRICT);
ini_set('display_errors', 'On');
ini_set('log_errors', 'On');
ini_set('error_log', $_SERVER['DOCUMENT_ROOT'] . '/php.log');
But when I use the first of the next two lines, my script issue a HTTP 500 error, and nothing is displayed (except the 500 error) and nothing is logged in my php.log. If I use the second line instead of the first one, all is OK and the 304 is issued normally.
开发者_开发百科header('Not Modified', true, 304); //Crash php with 500 error
header($_SERVER['SERVER_PROTOCOL'] . ' 304 Not Modified', true, 304); //Works OK
//In both case exit(); is called just after header().
Aren't these two lines equivalent (see link below)? Why the first version "crashes" my script?!
This is related to: Header use in PHP
Edit 1: This is the only log I can find:
'
69.70.84.xx - - [20/Jan/2010:15:54:06 -0600] "GET /framework2/ HTTP/1.1" 200 2968 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7 (.NET CLR 3.5.30729)"
69.70.84.xx - - [20/Jan/2010:15:54:08 -0600] "GET /foo/bar.js HTTP/1.1" 404 8642 "http://www.mydomain.com/framework2/" "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7 (.NET CLR 3.5.30729)"
69.70.84.xx - - [20/Jan/2010:15:54:10 -0600] "GET /framework2/ HTTP/1.1" 500 8511 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7 (.NET CLR 3.5.30729)"
69.70.84.xx - - [20/Jan/2010:15:54:11 -0600] "GET /framework/mydomain_ajax-dom.js HTTP/1.1" 304 - "http://www.mydomain.com/framework2/" "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7 (.NET CLR 3.5.30729)"
69.70.84.xx - - [20/Jan/2010:15:54:11 -0600] "GET /framework/templates/common/Reset.css HTTP/1.1" 304 - "http://www.mydomain.com/framework2/" "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7 (.NET CLR 3.5.30729)"
69.70.84.xx - - [20/Jan/2010:15:54:11 -0600] "GET /framework/templates/common/Error.css HTTP/1.1" 304 - "http://www.mydomain.com/framework2/" "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7 (.NET CLR 3.5.30729)"
69.70.84.xx - - [20/Jan/2010:15:54:11 -0600] "GET /framework/templates/common/Base.css HTTP/1.1" 304 - "http://www.mydomain.com/framework2/" "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7 (.NET CLR 3.5.30729)"
69.70.84.xx - - [20/Jan/2010:15:54:11 -0600] "GET /images/Error-48.png HTTP/1.1" 304 - "http://www.mydomain.com/framework2/" "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7 (.NET CLR 3.5.30729)"
'
- Line 1 is the document correctly served.
- Line 2 is the 404 of a dummy .js on my document.
- Line 3 is where the actual error occur (I hit refresh in my browser and my PHP issue the 304 header that crashes my script).
- Line 4, 5, 6, 7, 8 are caused by my custom error message (via .htaccess) that display the 500 error message.
Edit 2: I contacted Web host support to ask if I had access to more log they said no but on their side they have access to logs I can't see. My error was in there:
'backend: malformed header from script. Bad header=Not Modified: index.php'
So back to my question... Why on some hosts the first version don't work and on others it seems to be OK (even worse someone in the link above says that the second crashes while the first is OK)??
No, those lines are not equivalent. The first will write an invalid header line. The documentation to the header
function says:
header()
is used to send a raw HTTP header.
And in the description of the string parameter:
There are two special-case header calls. The first is a header that starts with the string "HTTP/" (case is not significant), which will be used to figure out the HTTP status code to send.
In your case the value Not Modified
does not start with HTTP/
and thus is not treated to set the HTTP status code but just a regular header field. But it is invalid as it does not has the form:
message-header = field-name ":" [ field-value ]
And that’s what the error log entry states. Not Modified
is not a valid raw HTTP header.
The third parameter http_response_code is just to set the status code while setting a redirection to avoid two header
calls like:
header('HTTP/1.1 301 Moved Permanently');
header('Location: http://example.com');
Instead of that you can simply write:
header('Location: http://example.com', true, 301);
You will want to check your web server error log, not your PHP error log in this case, to get more information about the crash.
精彩评论