Background

Script Security

OK, you've just spent a whole day working on your latest script, which you're terribly proud of. It has all these great features and it looks great!! But have you thought about security? Often, you'll be using a script which selects information from an SQL database, and is called like this: script.php?category_id=5. What if some hacker (or script kiddie) comes along and types in script.php?category=hack_me? 95% (OK, I may be exaggerating, but you get the point) of scripts these days will spit out some kind of cryptic error like this (a search on Google reveals roughly 36 000 of these!):

You have an error in your sql syntax near 'your precious SQL query here'.

Now that he/she has noticed that your script isn't secure, they can start messing around and creating chaos. What can you do against this? First of all, make sure that all data is of the type it should be? Don't let people type in letters for an ID, and don't let them put a space in an email address, for example. Then make sure they can't "escape" from your SQL query by adding a ' to a parameter (category_id=hack_me' AND ...).

Usability

It is quite helpful for the user to have URLs like this: http://www.yoursite.com/Category_Name/, rather then http://www.yoursite.com/?category=12345. This will enable them to know what page they are loading even before it loads.

Search Engines

Unfortunately for us web developers/designers, (most) search engines are a real pain about dynamic pages. As soon as a page shows the slightest sign of being dynamic, they often ignore it. This enables them not to crawl through a 15 000 page site, and not to bog down your server at the same time! This means that they will often ignore URLs like this: script.php?category_id=1. But what if you want them to visit it? Well, the best solution would be to change that URL to script/Cat_Name/. But how are you going to do that? Read on to find out...

Apache and mod_rewrite

To use the "mod_rewrite" method of making "elegant" URLs, you will need Apache v. 1.2 or later, with the mod_rewrite module installed (mod stands for module). Ask your host if you are unsure as to whether it is installed.

So what is mod_rewrite?

mod_rewrite is an Apache module which takes care of rewriting URLs, thus transforming: http://www.yoursite.com/script.php?category_id=1 into http://www.yoursite.com/script/cat_1/

So how is this different from a classic redirection? Well, the main difference is that this "redirection" is totally transparent to the end-user: he/she will not know that the URL has been rewritten. It therefore requires no special browser or software on the visitor's end.

Let's start

Firstly, you'll need to put the following code in a file named .htaccess, in whichever directory you are dealing with:

RewriteEngine on

Now the mod_rewrite module has been turned on, and is ready to accept further instructions. The RewriteRule command is the root of the module, which tells mod_rewrite what to do. Here is its syntax:

RewriteRule Pattern Substitute (Optional Flags)

Here's an example:

RewriteRule /articles/([0-9]+) /articles.php?id=$1

This will replace http://www.yoursite.com/articles/1/ with http://www.yoursite.com/articles.php?id=1.

You don't have to limit yourself to numbers either, you can use [a-z] or [A-Z] too!

Here are some flags you can use:

Not only can you rewrite URLs using rules, but you can also add conditions to these rules, so they won't be executed in every case:

RewriteCond Test Condition

Here's an example of what you can do with conditions:

RewriteCond %{HTTP_USER_AGENT} ^Opera.*
RewriteRule ^/$ /index_opera.php [L]

RewriteCond %{HTTP_USER_AGENT} ^Netscape.*
RewriteRule ^/$ /index_netscape.php [L]

RewriteRule ^/$ /index.php [L]

This will load a special page for Opera and Netscape, and load a default page for people not using Netscape. Here are some variables you can use in your conditions:

Get to work!

Now that I've (hopefully) wet your appetite, you can get working on some great uses of mod_rewrite. Here are some examples of what can be achieved:

/books/456/ » /index.php?mode=books&id=456
/books/456/buy » /index.php?mode=buy&id=456
/book_456.html » /index.php?book=456