Monday 19 May 2008

Custom 404 with PHP RedirectCustom 404 with PHP Redirect

Left QuoteSee my fancy custom URL's? You like? You want? Read on ...

This took me a while to figure out, so I thought I'd make a note of it, hopefully it'll save someone else from having the same problem.

In PHP we regularly need to pass variables from one page to another. The most common way of doing this is through the URL, which is why you see URL's like showthread.php?id=127 and view_article.php?article=483 etc. Wouldn't it be nicer (and more search-engine friendly) to have URL's like or ?

I'm going to assume a certain level of knowledge here. If you've read this far, I'll assume that you know what 404 and .htaccess files are, and that you're reasonably proficient in PHP. If not, the following might serve only to confuse ...

My aim for this article was to create a custom 404 page that would redirect the user without changing the URL address bar. For example, if someone entered, and I was using PHP's header() function to redirect to, the user would see the right page, but the URL address would be changed. I wanted this to happen without the URL rewrite, so the user would still see the /articles/websites URL, but the browser would display the content from the index.php?id=1 page.

If I was using ASP, I could use Server.Transfer but PHP doesn't have an equivalent, so the first step is to edit the .htaccess file to include the line ErrorDocument 404 /not_found.php. You then need to write a new not_found.php that looks through the supplied URL string to search for certain identifiers. In my case, the phrase '/articles/'. Having identified that, the rest of the string (eg 'websites') is used to search the database for an article with the same name. If it finds it, the user can then be redirected. Seeing as we can't use header() I decided to use include() instead.

Here's the problem with that ... you can't supply variables into include(), which means include("index.php?id=1") won't work. You can, however, do the following


Once you've checked that index.php correctly identifies the value of $_GET['id'], the next problem is that any calls to include() from inside index.php won't resolve, as the script will attempt to run them from the imaginary /articles/ directory. The way to solve this is to add the line <base href="" /> into the meta data at the top of the index.php page.

Lastly, having a custom 404 will return a 404: Page Not Found response, which tells search engines not to index that page, so make sure the first line of your not_found.php is

header("HTTP/1.0 200 OK");

And that's it ... job done! One "silent" redirect using PHP.Right Quote

Next article: ITA Submitted (12 June 2008)

Next Websites article: International Phone Number Format Function (27 February 2009)


Add your comments




4 + 4 = (this security question stops automated submissions)