Better Redirection

Here is some example code for doing redirection, a breakdown will follow.

<?php
$newpath="/";
$notificationemail="NOTwebmaster@phantomcode.com";
// Permanent redirection
$trackfile=$_SERVER["DOCUMENT_ROOT"]."/securedir/redirect.log";
touch($trackfile);
 $notice=date("dMt.H:i:s.T")."_".$_SERVER["SCRIPT_FILENAME"].":from:".$_SERVER["REFERRER"]."\n";
 if (is_writable($trackfile)) {
         if ($handle=fopen($trackfile,'a')) {
                fwrite($handle,$notice);
                fclose($handle);
                header("HTTP/1.1 301 Moved Permanently");
                header("Location: http://".$_SERVER["HTTP_HOST"].$newpath);
         }
         else{

                 emailerror("file: $trackfile could not be written\n".$notice);
         }
 }
 else{
         emailerror("file: $trackfile is not writable\n".$notice);
 }
 exit();

function emailerror($reason)
{
        if (!mail($notificationemail,"Site error: Redirect tracking failed",$reason)) {
                print "<!doctype html public \"-//w3c//dtd html 4.0 transitional//en\">\n<html><h
ead><meta http-equiv=\"refresh\" content=\"5;url=/$newpath\"></head><body><p>In 5 seconds you wil
l be redirected to: $newpath, please inform <a href=\"mailto:$notificationemail\">the webmaster</
a> that the automated redirect is no longer functioning.</p></body></html>";
        }
        else{   
              header("HTTP/1.1 301 Moved Permanently");                 
              header("Location:ttp://".$_SERVER["HTTP_HOST"].$newpath);
        }

}
?>

First, lets consider why you should do redirection in the first place. There is the obvious reason that you have not had time to fix all the links in your website but need to start pointing visitors to a new site. This is ideal for 301 type redirection. Essentially 301 redirection tells the browser that the file requested (your web page) has been permanently moved to a new location. From then on the browser can just ask for the new location instead of visiting the old one. 302 redirection is similar but indicates that the page might be back. There are more, see Wikipedia's article for more information.

An even better reason to do redirection is because other sites, search engines and code may point to web pages that you no longer maintain. Using redirection ensures that people get the resources you wanted to make available, even if those resources move.

Code Breakdown

<?php
$newpath="/";
$notificationemail="NOTwebmaster@phantomcode.com";
// Permanent redirection
$trackfile=$_SERVER["DOCUMENT_ROOT"]."/securedir/redirect.log";
touch($trackfile);

In this first section of code, we set a variable $newpath that will tell the browser where to go. It is handy to have the variable information since our redirect will also update a text file and might even email the webmaster. Note, pleas do not have your script use my email address. You can set this to a relative or a remote address.

We also set $trackfile as a location to record redirects. It is best to have only one tracking file, and this could be entered in a database for efficiency if your site is large enough to justify it. The first command is to 'touch' the data file since we will be opening it in append mode and this will ensure it is present.

$notice=date("dMt.H:i:s.T")."_".$_SERVER["SCRIPT_FILENAME"].":from:".$_SERVER["REFERRER"]."\n"; This is the real meat and reason for doing our own custom redirection. This code will allow us to know where the links are that are are sending our visitors to the wrong address. It allows you to put redirection in (as I have) with the intent of fixing any outdated links before removing the old structure. In this bit of code, the location of the redirection is recorded, the place that the redirection came from and when it occurred. You might want to add in the browser agent if you suspect a significant part of your observed redirections are coming from spiders or other automated tools.

 if (is_writable($trackfile)) {
         if ($handle=fopen($trackfile,'a')) {
                fwrite($handle,$notice);
                fclose($handle);
                header("HTTP/1.1 301 Moved Permanently");
                header("Location: http://".$_SERVER["HTTP_HOST"].$newpath);
         }

This ensures that the file that is used for recording the redirects is available and is opened before it attempts to write. This is an important consideration since the redirect tracking file could potentially be unavailable if the permissions get set incorrectly. This is also where you could change the script to point externally if needed, since this script assumes redirection within the same website.

         else{

                 emailerror("file: $trackfile could not be written\n".$notice);
         }
 }
 else{
         emailerror("file: $trackfile is not writable\n".$notice);
 }
 exit();

If something goes wrong with recording the redirect, the script falls back on providing the same information plus the reason for the failure in recording via email. The exit(); directive is not really necessary in this script but is a good habit.

function emailerror($reason)
{
        if (!mail($notificationemail,"Site error: Redirect tracking failed",$reason)) {
                print "<!doctype html public \"-//w3c//dtd html 4.0 transitional//en\">\n<html><h
ead><meta http-equiv=\"refresh\" content=\"5;url=/$newpath\"></head><body><p>In 5 seconds you wil
l be redirected to: $newpath, please inform <a href=\"mailto:$notificationemail\">the webmaster</
a> that the automated redirect is no longer functioning.</p></body></html>";
        }
        else{   
              header("HTTP/1.1 301 Moved Permanently");                 
              header("Location:ttp://".$_SERVER["HTTP_HOST"].$newpath);
        }
}

This is our failure function which will email us if there is a problem recording the redirect in the desired file. It makes sure that the system confirms the email is successful before doing the redirection. If it is not able to send the email, it switches to doing html page based redirection to give the end user the opportunity to notify you by email of the problem.