views:

245

answers:

5
+3  Q: 

Header use in PHP

Pretty simple question: which one of these two PHP (version 5+) header call is the "best"?

header('Not Modified', true, 304);
header('HTTP/1.1 304 Not Modified');

I'm pretty sure the first one is the most polyvalent one, but just curious if PHP would "fix" the second one if under HTTP 1.0...

Thanks!

Edit: One of these header crashes PHP on my Web host. Follow-up question at: http://stackoverflow.com/questions/2104655/php-header-call-crashing-script-with-http-500-error

+2  A: 

I'd go with the second one, as the http response code argument is only supported >= PHP 4.3.0 (which could affect code portability).

I've done this many times and not come across any client that doesn't support HTTP/1.1, so unless you have a special case I shouldn't think that would ever be a problem.

adam
why do you care about php4 compatibility? don't you use objects (or use them in a very limited way)?
valya
Indeed, I consider PHP 4 cold dead. I no longer support PHP < 5 in any of my script.
AlexV
Quite, but there are still a large number of PHP 4 servers so if there was any need for the code to be portable then it's a consideration.Why do you still care about HTTP/1.0?
adam
Yeah I know that there are a number of PHP 4 servers out there, but I just don't use/support them. I don't want PHP 4 to be another IE 6...I don't really care about HTTP 1.0, but since I can control the PHP version I run and not the HTTP version used in the query, I prefer answer in the same "language" as the query was made.
AlexV
+4  A: 

There are two things about the behaviour of the first header call that are worth pointing out:

  • If you provide the 3rd argument, PHP will ignore the first string argument and send the correct response for the given number. This might make the first method less prone to programmer errors.
  • PHP seems to respond with a HTTP/1.1 response even when the request was made with HTTP/1.0
Ben James
Seems that the first point is not true (at least for my Webhost) as I get "backend: malformed header from script. Bad header=Not Modified: index.php"...
AlexV
+2  A: 

I would normally go with the second example - however, when recently benchmarking an application using apachebench, we noticed ab hanging often.

After debugging, it was identified that the header in this style:

header('HTTP/1.1 304 Not Modified')

Was the culprit (Yeah, I have no idea) and after changing it to,

header('Not Modified', true, 304);

Believe it or not ab started working. Very strange but something to think about. I'll probably use the second method going forward.

Mr-sk
Strange... My host crash with a 500 error when using header('Not Modified', true, 304); (I get error "backend: malformed header from script. Bad header=Not Modified: index.php ").
AlexV
+3  A: 

I would use this one:

header($_SERVER['SERVER_PROTOCOL'].' 304 Not Modified', true, 304);

$_SERVER['SERVER_PROTOCOL'] contains the protocol used in the request like HTTP/1.0 or HTTP/1.1.


Edit    I have to admit that my suggestion is senseless. After a few tests I noticed that if the first parameter is a valid HTTP status line, PHP will use that status line regardless if and what second status code was given with the third parameter. And the second parameter (documentation names it replace) is useless too as there can not be multiple status lines.

So the second and third parameter in this call are just redundant:

header($_SERVER['SERVER_PROTOCOL'].' 304 Not Modified', true, 304);

Use just this instead:

header($_SERVER['SERVER_PROTOCOL'].' 304 Not Modified');
Gumbo
+1  A: 

I think Gumbo's answer is the most sensible so far. However try this:

<?php
header('Gobbledy Gook', true, 304);
?>

If the first string is not a proper header it is discarded. If iy does look like a valid header it is appended to the headers - try this:

<?php
header('Cache-Control: max-age=10', true, 304);
?>

RTFM for header() and note the special cases - in general I think its not advisable to rely on such built-in heuristics.

However, I'm guessing that your actually interested in getting the content cached well by proxies/browsers. In most instances, latency is far more of a problem of a problem than bandwidth. Next consider how a browser behaves when cached content is stale - in the absence of updated caching information, it keeps making repeated requests to the server to see if the content is still stale.

I.e. in most cases ignoring the conditional part of requests (or even better stripping them on the webserver) actually improves performance.

C.

symcbean
"If the first string is not a proper header it is discarded. If iy does look like a valid header it is appended to the headers" are you sure of that? When I use header('Not Modified', true, 304); I get error "backend: malformed header from script. Bad header=Not Modified: index.php" is it because of that?
AlexV