mod_rewrite: A Beginner’s Guide to URL Rewriting

Share this article

For Advanced Users

I mentioned user-friendliness in the introduction, and haven’t dealt with it. First, let’s imagine we’re having a huge download site that has the downloadable software separated into categories, each with a unique id (which is used in the SQL SELECTs). We use links like open.php?categoryid=23487678 to display the contents of a category.

To ensure that our URLs were easily memorized (eg. http://www.downloadsite.com/Nettools/Messengers) we could use:

  RewriteRule ^/NetTools$ /test.php?target=3    
 RewriteRule ^/NetTools/Messengers$ /test.php?target=34

assuming the ID is 3 for the NetTools category and 34 for Messengers subcategory.

But our site is huge, as I’ve mentioned – who wants to hunt down all the IDs from the database, and then edit the config file by hand? No-one! Instead, we can use the mapping feature of mod_rewrite. Map allows us to provide a replacement-table – stored in a single text file — within a hash file (for fast lookups), or even served through an external program!

For better performance I’d generate a single text file using PHP, which contains the following:

  NetTools            3    
 NetTools/Messengers 34    
 .    
 .    
 .    
 and so on.

The httpd.conf file would contain:

  RewriteMap categories txt:/path/to/file/categoryids.txt    
 RewriteRule ^(.*)$ open.php?categoryid=${categories:$1|0}

These lines tell mod_rewrite to read the categoryids.txt file upon Apache startup, and provide the ID for the URL for open.php. The |0 means that categoryid will be 0 if there’s no matching key in the textfile.

You can also choose to serve the IDs on-the-fly via a script or other executable code. The program is started by Apache on server startup, and runs until shutdown. The program must have buffered I/O disabled, read from the stdin, and write results to stdout — it’s that simple!

With RewriteMap you can do a lot more, including:

  • load balancing through servers (using rnd:),
  • creation of a Webcluster that has an homogenous URL layout,
  • redirection to mirror sites without modifying your Web application,
  • denial of user access based on a hostlist,

and so on.

Tips, Tricks and Advice

  1. Before using mod_rewrite in a production server, I’d recommend setting up a testserver (or playground, whatever you prefer to call it).
  • During development, you must avoid using ‘old-fashioned’ URLs in your application.
  • There might still be need to verify data passed through the URL (passing non-existing — too large or small – IDs, for example, might be risky).
  • Writing ‘intelligent’ RewriteRules saved me coding time and helped me write simpler code. I’m using error_reporting(E_ALL); everywhere (and I recommend it!), but I find it boring to do the following for the ten thousandths time:
  • if (isset($_GET['id']) && (validNumber($_GET['id']))    
    if (isset($_GET['todo']) && ($_GET['todo']=='deleteitem'))

    The following trick helped me to get rid of the extra isset() expression by providing all the needed parameters each time in the RewriteRules:

    RewriteRule ^/products/[0-9]+$ products.php?id=$1&todo=

    I know, I know it’s not the answer to the meaning of life — but it’s hard to show how nice and clear a solution this might provide in such a short example.

    Finally …

    That’s all for our ‘brief’ overview of mod_rewrite. After you’ve mastered the basics, you’ll find you can easily create your own rules. If you like the idea of URL rewriting, may want to play with mod_rewrite – some ideas follow (note that the underlying PHP code is not important in this case):

    http://www.mysite.com/1/2/3/content.html    
       => 1_2_3_content.html    
       http://www.mysite.com/1/2/3/content.html    
       => content.php ? category=1    
       
       http://www.mysite.com/1/2/3/    
       => content.php ? category=1 & subcat1 = 2 & subcat2 = 3    
       
       http://www.mysite.com/1/2/3/details    
       => content.php ? category=1 & subcat1 = 2 & subcat2 = 3    
       http://www.mysite.com/bookshop/browse/bytitle    
       => library.php ? target=listbooks & order = title    
       http://www.mysite.com/bookshop/browse/byauthor    
       => library.php ? target=listbooks & order = author    
       
    http://www.mysite.com/bookshop/product/123    
       => library.php ? target=showproduct & itemid=123    
       
    http://www.mysite.com/bookshop/helpdesk/2    
       => library.php ? target=showhelp & page=2    
      http://www.mysite.com/bookshop/registration    
       => library.php ? target=reg

    Links

    1. Search Engine Friendly PHP Pages, by John Coggeshall
    2. Search Engine-Friendly URLs, by Chris Beasley
  • “IISRewrite is a stripped down implementation of Apache’s mod_rewrite module for IIS”
  • If you enjoyed reading this post, you’ll love Learnable; the place to learn fresh skills and techniques from the masters. Members get instant access to all of SitePoint’s ebooks and interactive online courses, like PHP & MySQL Web Development for Beginners.

    Go to page: 1 | 2 | 3 | 4
    Tamas TurcsanyiTamas Turcsanyi
    View Author

    Tamas is the founder of Demoscene, and has created dozens of PHP-based sites. Now he's doing ebusiness work for IFS Ltd. in Hungary, and composing jazzy drumnbass and bigbeat tunes, which he hopes to have released.

    Share this article
    Read Next
    Get the freshest news and resources for developers, designers and digital creators in your inbox each week