Header in PHP overrides the HTTP Response code

2019-07-04 21:27发布

问题:

Working around setting rules at Apache level, Found that header('Location: filename.php') in php overrides the response code. Look at the below code :-

<?php
header('HTTP/1.1 308 Permanent Redirect'); //or Try for 4xx/5xx Code
header('Location: http://hello.php');
?>

Expected result

  • HTTP/1.1 308 Permanent Redirect
  • Host: localhost:8000
  • Location: hello.php
  • Connection: close
  • X-Powered-By: PHP/5.5.6

Actual result

  • HTTP/1.1 302 Found
  • Host: localhost:8000
  • Location: hello.php
  • Connection: close
  • X-Powered-By: PHP/5.5.6

Is something wrong at Apache level or its Bug in PHP ?

Update:

回答1:

As per the function documentation page this is the desired behaviour of PHP when sending the Location header.

EDIT: Sorry, misread your message. It will override the response code if you send a code different than 3xx, so it should work with a 308. Are you sure that no other HTTP code is sent back ? Does your client tries to retrieve the new resource and you see the 302 as a final result ?

FINAL EDIT: Did you try

header('Location: /some/page.php', TRUE, 308);


回答2:

As mentioned in PHP documentation of header(), there is a special case for "Location" type of header. It sets 302 response code unless the 201 or a 3xx status code has already been set . Unfortunately it doesn't work as you can see on your example.

I've played with code and looks like it works when you change the order of operations like this:

<?php
header('Location: landing.php');
header('HTTP/1.1 308 Permanent Redirect');
?> 

It seems that header('Location ... overrides the response code in any case but doing header('HTTP/1.1 308... after it change it back to 308.

Did some extra investigations and here is the result.

header('Location: http://smth');

doesn't change the response code for 3** except 308. So if you do

<?php
header('HTTP/1.1 307 Temporary Redirect');
header('Location: landing.php');
?> 

the code above will work ok as expected. So you're 'lucky' to find exception in the rule. While my workaround allows to solve the issue. PS: Using PHP 5.4.27