Anne van Kesteren

Permanent redirect in PHP

It is Sunday again. I must say I really like the new feeds released last week. This week a little reminder. I always thought that the following code enabled the correct server side 301 redirect in PHP:

<?php
 header("Location: http://example.org/foo");
?>

However, I recently found out that it gives back a 302 to the browser. This is a good thing for most scripts, since unlike a 301, a 302 status code means that the redirect should not be cached and the browser should retrieve the same location again. However, if you actually moved something to a new location (forever) use:

<?php
 header("HTTP/1.1 301 Moved Permanently");
 header("Location: http://example.org/foo");
?>

Comments

  1. And if /foo is actually a directory, you should really link straight to /foo/, so as to avoid another, redundant 301 redirect from the example.org server. :)

    Posted by Christopher at

  2. Ah, brilliant.
    Call it coincidence, but this is exactly what I'm going to need in a couple of days time. I'm changing servers soon, and have been meaning to look into how to do this when it popped into my feed reader just now. Thank you very much for making it easier for me, even if you didn't mean to. :-)

    Posted by Ashley at

  3. I always prefer to arrange these kind of things in the server configuration instead of in a document.

    Posted by Jeroen at

  4. You can use the third argument to PHP's header function to provide a specific status code. E.g.,

     <?php  header('Location: http://example.org/foo', true, 301); ?> 

    Posted by Louis Bennett at

  5. Another alternative: <?php header("Status: 301\nLocation: /foo"); ?>

    If I'm not mistaken (probably not, it seems to work fine on my test server) Apache will correct the Status header to the right one, including HTTP version and the Moved Permanently test.

    Posted by Mark Wubben at

  6. Mark, I believe it is not allowed to use relative URIs per the specification.

    Louis, thanks. That is certainly useful.

    Jeroen, what if you have to do about 1000 redirects? Using PHP to query the new URI out of the database and redirect accordingly is much easier. However, for simple file redirects you should certainly take advantage of the server capabilities.

    Posted by Anne at

  7. Mark, I believe it is not allowed to use relative URIs per the specification.

    AFAIK it is only valid in HTTP 1.0 and not 1.1

    Posted by Charl van Niekerk at

  8. Anne, the thousand redirects would usually be in the form of page.php?argument=something&secondargument=somethingelse, wouldn't they? That would be easy to do via the server as well...

    Posted by Frenzie at

  9. You should also add: header ("Connection: close"); for one browser that is not that good (you know which one that is, don't you?)

    Posted by dusoft at

  10. I think it's worth mentioning 410 Gone, which is terribly underused.

    Posted by Evan Nemerson at