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

Apache's Mod Rewrite

The first method we will look at is the mod_rewrite module that comes with Apache. This module works by matching the requested URL against a set of predefined rules, and then passing in the data to the specified script in the format you determine.

Let’s say that we have a script called news.php in the root directory of the web site (so you could access via http://www.example.com/news.php). This script is responsible for outputting a single news article, as chosen by the news_id parameter passed in the URL.

So if you were trying the access the new article with an ID of 63, you would use http://www.example.com/news.php?news_id=63.

Instead though, we want to make this a bit fancier, so rather than passing an in the URL, we want to access articles using http://www.example.com/news/63.html. There’s no particular reason for having it like this – it’s just for our example.

Anyway, we can make this happen with mod_rewrite with a very simple rule, either in the web server config (httpd.conf), or in a .htaccess file in the web site directory.

The contents would look like this:

Listing 1 .htaccess
RewriteEngine on
RewriteRule ^/news/([0-9]+)\.html /news.php?news_id=$1

Using the above regular expression, we match all requests to the web site that start with news, then have a number followed by .html. Items stored in brackets are stored in variables, such as $1 or $2 (we only have one set of brackets so only $1 is set here).

We then use the $1 parameter in the destination URL. Now inside the news.php script, we just access the news_id parameter as we would have if we called the script in the original way. That is:

Listing 2 news.php
<?php
    $news_id = $_GET['news_id'];
?>

Extra URL parameters

Sometimes you have a situation where you want to pass extra URL parameters to the script. So going back to our example above, perhaps you can access the news.php script with an extra parameter called ‘print’, which displayed a printer friendly version of the article (technically you should be using CSS stylesheets for this, but that doesn’t matter for this example).

So you would normally access the printer friendly version of article 63 using http://www.example.com/news.php?news_id=63&print=1.

Using our rewrite version, we want to access the article using http://www.example.com/news/63.html?print=1, however, the rule we created above will simply discard the print parameter in the URL. To pass this to the news script, we need to use the internal Apache variable %{QUERY_STRING} in our mod_rewrite pattern. We just append this to the news_id with an ampersand.

Listing 3 .htaccess
RewriteEngine on
RewriteRule ^/news/([0-9]+)\.html /news.php?news_id=$1&%{QUERY_STRING}

So now, we can access both parameters through $_GET.

Listing 4 news.php
<?php
    $news_id = $_GET['news_id'];
    $printVersion = isset($_GET['print']);
?>

So that’s all there is to using mod_rewrite. This is a very powerful and complex module, and it is easy to get into trouble using it. Sometimes it can be hard to get your patterns to match correctly, or you create recursive rules, etc. There are several debug settings you can use to try and resolve any problems you might have.

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