2

Short question: Can I rely on the behaviour of header('.', TRUE, 404);, header('.', TRUE, 501);, etc.?

Now, let me elaborate.

Before asking my question, I'll present a few usages of the header() call and the corresponding HTTP response code generated by it.

header('HTTP/1.1 404 Bummer!'); -- HTTP/1.1 404 Bummer!

header('HTTP/1.1 501 I am sick'); -- HTTP/1.1 501 I am sick

header('Bummer!', TRUE, 404); -- HTTP/1.1 404 Not Found

header('I am sick', TRUE, 501); -- HTTP/1.1 501 Method Not Implemented

So, we can see that if we use the third parameter while the first parameter is junk, the first parameter is ignored. However, the documentation at http://php.net/manual/en/function.header.php says:

Note that this parameter only has an effect if the string is not empty.

So, we still have to put something in the first parameter. This looks a bit ugly to me because the $string is ignored when we specify $http_response_code in the third parameter but we are still required to put some value for $string even though it will never be used.

But I can understand why this turned out this way. Traditionally, header() accepted only parameter and we could set arbitrary response codes like in the first two examples. The second and third parameters were added later as optional paramters. So, we have to specify something for the first parameter if we want to use the second and third. Moreover, sometimes we may need to put valid headers in the first parameter along with a valid response code in the third parameter. I have included one such example in the end.

So, I'm planning to use this function in this manner in my code: header('.', TRUE, 404);, header('.', TRUE, 501);, etc. As per the examples above, it'll produce correct HTTP responses as per the standard. I want to know if I can rely on this behaviour. I ask this question because I can't find the documentation mentioning explicitly that the first parameter ($string) is going to be ignored when we provide the third ($http_response_code).

BTW, I know that the first argument can be useful in situations like this.

header('Foo: Bar', TRUE, 501); leads to:

HTTP/1.1 501 Method Not Implemented
Date: Sun, 09 Oct 2011 19:01:19 GMT
Server: Apache/2.2.20 (Debian)
X-Powered-By: PHP/5.3.8-1
Foo: Bar
Vary: Accept-Encoding
Connection: close
Content-Type: text/html

A more practical example is header('Location: http://example.com/there/', TRUE, 307); which would generate:

HTTP/1.1 307 Temporary Redirect
Date: Sun, 09 Oct 2011 19:09:29 GMT
Server: Apache/2.2.20 (Debian)
X-Powered-By: PHP/5.3.8-1
Location: http://example.com/there/
Vary: Accept-Encoding
Content-Type: text/html

Anyway, back to my question. Can I rely on the behaviour of header('.', TRUE, 404);, header('.', TRUE, 501);, etc.?

NullPoiиteя
  • 56,591
  • 22
  • 125
  • 143
Susam Pal
  • 32,765
  • 12
  • 81
  • 103

2 Answers2

3

Not sure if you're looking for this, but I guess you don't want to build the HTTP status line:

header('.', TRUE, 501);

Makes my Apache return this status line:

HTTP/1.1 500 Internal Server Error

But

header(' ', TRUE, 501);

Makes my Apache return this status line:

HTTP/1.1 501 Not Implemented

Which might be what you're looking for.

Maybe you just want to build the status line?

header('HTTP/1.1 501 No Implementation for you :)');

Which makes my Apache return this status line:

HTTP/1.1 501 No Implementation for you :)

Traditionally, it's done this way:

header('HTTP/1.1 501');

Which get's some default status line message text then:

HTTP/1.1 501 Method Not Implemented

This does not change the protocol version:

header('HTTP/1.0 404');

As it gives:

HTTP/1.1 404 Not Found

Hope this helps.


Update by Susam:

With PHP 5.4, a simple and elegant way to do this is:

http_response_code(404);

or

http_response_code(501);
Community
  • 1
  • 1
hakre
  • 193,403
  • 52
  • 435
  • 836
  • Interesting bout protocol version and added message. Do you have a reference that this'll work on other web servers too? – NikiC Oct 09 '11 at 19:38
  • `header('HTTP/1.1 404')`, `header('HTTP/1.1 501')`, etc. certainly looks clean. I hope I can rely on this. I am going to use this: `header("{$_SERVER['SERVER_PROTOCOL']} 501");`. This will make sure that we use the correct HTTP version in the response automatically without having to rely on the web server to correct it. – Susam Pal Oct 09 '11 at 19:41
  • @NikiC: Changing the HTTP Status Line is documented on PHP.net `header()` page. There are two special headers, the HTTP Status Line one and the Location one, which automatically sets the 301 response code if no code is specified. That's on PHP's side. With a F/CGI interface it's as well up to the server what it does with returned status line and other headers from the script. So it's not always predictable, but as long as PHP is concerned, just use the status line special header if unsure. http://php.net/header – hakre Oct 09 '11 at 19:43
1

There's currently no function to only set the numeric HTTP response code. However, I think PHP 5.4 will finally fill this void with http_response_code().

I wouldn't use header(".", TRUE, 501) myself. It might work on some web server software but very unlikely to work on them all.

Kaivosukeltaja
  • 15,541
  • 4
  • 40
  • 70