A More Useful 404 - PHP Edition

In its most recent issue as of this posting (Issue #272), A List Apart released an article entitled A More Useful 404. This article laid forth a method of how to write a 404 page that's useful to both web administrators and users alike - one that will e-mail the admin an error e-mail letting them know what kind of 404 error there was, and a custom error message for the user that can help point them in the right direction, or at least let them know about the problem.

My only problem with the article (and it's not really a problem, so calm down old Perl guy in the back) is that all of the code that was presented was done in perl. So I took it upon myself to rewrite the code in PHP. The code is below, and in downloadable form as well. The only variables you should have to change are the e-mail addresses at the top for who it should be mailed to - everything else should be fine.

The way I implemented it - there are no messages that are directly outputted - just a variable is set as to what kind of error you have with the 404. This way, they can be implemented in a template, or in my general use, outputted for formatting in a Smarty template.

To implement this as a 404 error document, in apache, use the first block of code in an .htaccess file. (obviously, change the URL if you're saving it in a different place) The rest of the code goes in your 404 page.

.htaccess


ErrorDocument 404 /errorpages/404-error.php

404-error.php Download this file


## E-Mail Variables

$from = "From: info@chris-parsons.com";
$to = "info@chris-parsons.com";

## Search Engines

$search_engines[] = "google.com";
$search_engines[] = "live.com";
$search_engines[] = "msn.com";
$search_engines[] = "aol.com";
$search_engines[] = "yahoo.com";
$search_engines[] = "cuil.com";
$search_engines[] = "viewzi.com";
$search_engines[] = "searchme.com";
$search_engines[] = "ask.com";
$search_engines[] = "baidu.com";
$search_engines[] = "altavista.com";
$search_engines[] = "excite.com";

## Code to check for source of bad link
## $error = "user" means that it's a bad bookmark or a typo by the user
## $error = "internal" means you have a bad link on your site
## $error = "engine" means that there's a bad link coming from a search engine
## $error = "external" means it's a bad link from another website

## Checks to see if they came from a bookmark or from typing in the URL
if ($_SERVER['HTTP_REFERER'] == '') {
$error = "user";
}
## Checks to see if it was an internal link from the same website
else if (strpos($_SERVER['HTTP_REFERER'],$_SERVER['SERVER_NAME'])) {
$error = "internal";
$subject = "Broken Internal Link on " . $_SERVER['SERVER_NAME'];
$message = "There's a broken link on the page " . $_SERVER['HTTP_REFERER'] . ".\n";
$message .= "The link ends up going to " . $_SERVER['REQUEST_URI'] . ".";
}
else {
## This checks to see if it came from a search engine in the list
## In the future, this could be expanded to strip the keywords from the
## query to determine the search made
## Use apache and redirect this link with a 301 to fix the problem correctly
foreach ($search_engines AS $engine) {
if (strpos($_SERVER['HTTP_REFERER'],$engine)) {
$error = "engine";
$subject = "Broken Search Engine Link on " . $_SERVER['SERVER_NAME'];
$message = "There's a broken link from " . $engine . ".\n";
$message .= "The link they came from is " . $_SERVER['HTTP_REFERER'] . ".\n";
$message .= "The link ends up going to " . $_SERVER['REQUEST_URI'] . ".";
break;
}
}
## If all of the above have failed, then it's a link from another website
if (!$error) {
$error = "external";
$subject = "Broken External Link on " . $_SERVER['SERVER_NAME'];
$message = "There's a broken link on the page " . $_SERVER['HTTP_REFERER'] . ".\n";
$message .= "The link ends up going to " . $_SERVER['REQUEST_URI'] . ".";
}
}

if ($subject) {
mail($to, $subject, $message, $from);
}

For an example, try clicking on the link to http://www.turnedleafstudios.com/missing-page.php and then try copying it into your address bar to see the difference.

If you run into any issues, please drop me a line via the contact form - I'll be glad to look over any problems.

About the Author

I’m Chris Parsons, and I’m a freelance web developer located in Deerfield Beach, Florida. I specialize in the Drupal content management system, specifically with theming and implementation. Find out more about my background, both professional and personal, by visiting my About Me page.

Comments

書いてください。 バイアグラ バイアグラ

Post new comment

The content of this field is kept private and will not be shown publicly.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Lines and paragraphs break automatically.

More information about formatting options