PhpRiot
Become Zend Certified

Prepare for the ZCE exam using our quizzes (web or iPad/iPhone). More info...


When you're ready get 7.5% off your exam voucher using voucher CJQNOV23 at the Zend Store

Creating Search Engine Friendly URLs In PHP

Using A Custom 404 Handler

This is probably the most complicated method of achieving this result, however, it is also the simplest to expand upon and is more powerful.

By taking advantage of Apache’s custom 404 handler, you can have a single controlling script that decides how all requests are handled. Of course, this is only requests that do not match an existing file. For example, if you have images on your web site, you can still access them in an identical fashion — the image file will exist, hence the 404 handler will not be used.

Additionally, by taking advantage of PHP’s header() function, you can output, say, a 200 OK header rather than a 404 File Not Found header, so from the end user’s point of view, they have no idea the page wasn’t really found.

An example of where this would be used

Taking this idea further, you probably wouldn’t bother implementing a system like this for just a news handling engine as in our examples, but rather, on a larger site that has a lot more content.

For example, if you look at the following URL: http://www.phpriot.com/d/articles/php/index.html. PhpRiot is actually using the ‘ForceType’ method with a PHP script called ‘d’ that handles requests, but we could have implemented it using this method.

Note: This URL was used in a previous version of PhpRiot - the URL scheme of the site no longer works in this fashion.

Suppose we wanted our URL to look like this: http://www.phpriot.com/articles/php/index.html. Instead of creating this path on our web server for each and every article, we would use the 404 handler to parse out the article path like we currently do with our d file.

Implementing the 404 handler

We’re not going to implement the example listed above as it involves other complexities not relevant to this article, so instead, we’ll implement our news article example. We’re also going to add in scope to handle other requests (other than news) and also for outputting error pages.

The first thing to do would be to setup the 404 handler. This can be done either in a .htaccess or in the httpd.conf.

Listing 8 .htaccess
ErrorDocument 404 /handler.php

This means that all requests that don’t match an existing file, are passed to the handler.php script in our web root.

So in this script, we need to parse out the request. You can find the original request in the server REDIRECT_URL variable.

Listing 9 handler.php
<?php
    $request = $_SERVER['REDIRECT_URL'];
 
    // explode on / to find all the different request parts
    $parts = explode('/', $request);
 
    // flag to determine whether or not we've found content
    $found = false;
 
    // the first element will be empty to we get rid of it
    array_shift($parts);
 
    // now we determine the type of content
    switch ($parts[0]) {
        case 'news':
            // use a very similar regex to our previous example
            preg_match('!^(\d+)\.html$!', $parts[1], $matches);
            $news_id = (int) $matches[1];
 
            $output = getNewsArticle($news_id);
                // this function doesn't really exist, but if it
                // did it would return the news content if article
                // found, or return null if not
 
            if ($output !== null)
                $found = true;
 
            break;
 
        case 'articles':
            // here we would implement a handler to display a document,
            // say if they accessed http://www.example.com/documents/1234.html
 
            break;
 
        default:
 
    }
 
    if ($found) {
        // output a header to say the content exists, other a 404 will be sent
        header('HTTP/1.1: 200 OK');
        echo $output;
    }
    else {
        // no content was found. this should be automatically sent by the
        // server anyway, but we'll specify anyway just in case
        header('HTTP/1.0 404 Not Found');
        echo 'File not found';
    }
?>

Obviously this script is slightly crude, but hopefully in its simplicity you can see how powerful this method can be and what possibilities it can open.

In This Article


Article History

Jan 10, 2006
Initial article version
Feb 28, 2008
Added the "Using mod_rewrite as a 404 Handler" page to the article