Redirect visitors with a custom 404 error page.

Introduction.

The idea of this page is to show you how to redirect visitors to a new location using PHP if, for example, you move your website content around but wish to redirect traffic to the new page from the old location.

The principle is that any link to the old location will result in a 404 error since the page no longer exists in that location. However if we use a custom 404 page using PHP we can identify the requested page and if this URI matches a page we specify we can then redirect the visitor to the new page.

About sending 301 (permanently moved) headers.

For the visitor it will appear seamless but also for search engines we set the redirect up so it also sends a 301 header, telling the search engine the page has permanently moved.

It's very important that you use 301 header and not the more common 302 header, if you don't specifically send the header with PHP then Apache will send a 302 header as soon as the header("location: ") occurs.

This means the page has temporarily moved so search engines will not update their links to point to the new location. If you send a 301 header then the search engines should update their index to point to the new location. This definitely works for at least Google and Yahoo in my experience but may take from a few days to weeks to occur depending on your site.

Make a .htaccess file.

If you don't already have a .htaccess file then add one to the root of your website with the location of your custom 404 error page. A .htaccess file is just a plain text file called .htaccess, on Linux the '.' makes this a hidden file but you should also change the permissions of the file to 644 so it cannot be opened in a browser. To use a custom error page simply add the following line to the file:

ErrorDocument 404 /errors/404error.php

Edit the path and filename to match your site of course, relative to your sites root. Now Apache will use this file whenever a web page cannot be found.

The redirect script.

<?php 
$request=$_SERVER['REQUEST_URI'];

$arrMoved=array("/path/oldname.php"=>"/path/newname.php",
	        "/old_path/oldname.php"=>"/new_path/newname.php");
           
if(array_key_exists($request,$arrMoved))
    {
    $newplace="http://".$_SERVER['HTTP_HOST'].$arrMoved[$request];
    header("HTTP/1.0 301 Moved Permanently");
    header("Location: $newplace");
    header("Connection: close");
    exit();
    }
else
    {
    header("HTTP/1.0 404 Not Found");
    }
    
?>

<!-- 
Your normal HTML code goes here since if a match is found the visitor will have been redirected. Only genuine 404 errors will see the HTML below.
 -->
 
<html>
  <head>
    <title>404 Error page</title>
  </head>
  <body>
    <p>Sorry but this page isn't here.</p>
  </body>
</html>

How the script works.

Identify the requested page.

This very simple script just gets the request URI from the server variables, this will be the address of the page (relative to the root of your site) that was requested, since this request has caused a 404 error this could either be a page you have moved or a page that never existed.

Next I've set up an associative array containing the old page as index and new page location as key. Using the array_key_exists function I check to see if the requested page matches a key in the array. If there is no match in the array then it must be a genuine 404 error so I send the correct header("HTTP/1.0 404 Not Found") and the script will then continue so the regular HTML for your custom 404 error page is sent to the browser.

Redirecting the visitor.

If a match is found in the array then I just add the matching new location to the servers 'HTTP_HOST' variable to get the full path.

Next I send the 301 header so the search engines know the page has moved permanently followed by the actual redirect to the new page location. Finally the exit() statement stops further execution of the PHP script.

About the header codes.

Note that you must send the 404 header in the script otherwise this page will just (to search engines at least) look like a normally accessed page meaning that Apache will send a header status 200 (OK). The effect of this will be that any request made to your site for a non existant page will look to search engines as though it actually exists, i.e. all pages will return a 200 OK status.

If you use a Google Sitemap then you will know that before you can use the service Google runs some checks including uploading a randomly named file to see you are the site administrator but they also check the header response for a genuine page and a randomly generated page that will not exist on your website.

This is done to check that the response code for an existing page is 200 OK and a missing page return 404. If your custom error page doesn't send a 404 header then every request to your website will return a 200 OK status and search engines will have no way of telling which pages do and do not exist on your web site.

Checking the script.

To test all is working well just point your browser to a page you have moved and see that the server redirects you to the new page location. On my site that isn't that many pages where I don't move pages around much this works very well and is very easy to use.

If you needed a larger scale you could always put the old and new location into a 2 field MySQL table. Using the old location as a primary key the script could easily select the row from the table that matches the requested page, if the result set is empty it means there were no matching records so you have a genuine 404 error. Otherwise you will have the new page location returned that you can use for the redirect.

If you monitor your web logs then you will see the 301 status showing this working. After the search engine listings are updated you can remove the pages from the array if you wish but of course anyone that has bookmarked the old location will not then be redirected to the new page so it does no harm to leave them there.