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:
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);
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