mod_rewrite: A Beginner’s Guide to URL Rewriting

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

    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

    Free book: Jump Start HTML5 Basics

    Grab a free copy of one our latest ebooks! Packed with hints and tips on HTML5's most powerful new features.

    • Pellumb Hasani

      Hey Tamas, this is the best guide for url rewriting, that ive found. I am new to url rewriting and this guide helped me to understand it, and to get started with it.

      Thanks very much for this great guide ;)