Fancy Flat URL’s with htaccess

I’m putting this here because it took me a little bit of tweaking to actually get it
right. I always forget these .htaccess tricks and have to look them up. So I decided tp preserve this one here so I can easily find it next time I need it.

The trick is simple – I want to transform ugly looking URL’s with GET query string into neat looking, human readable addresses – kinda like the ones in Rails and similar frameworks. Let’s say you have a file called index.php in the directory foo that’s located in your web root. The script accepts three GET attributes and does something based on what they are. Your normal URL would therefore look like this:

http://example.com/foo/?module=bar&action=view&id=12

It’s long, ugly and almost unreadable to the average user. I want my URL to look more like this:

http://example.com/foo/bar/view/12

Short, nice, readable and also easy to figure out. How do you accomplish this? With a little bit of htaccess magic. For me this setup worked:

Options +FollowSymlinks
RewriteEngine on
RewriteBase /foo/
 
RewriteRule ^([^/]+)/([^/]+)/([^/]+)$ index.php?module=$1&action=$2&id=$3 [NC]

The RewriteBase thing is important if you want your application run in it’s own directory. Seriously, I spent like 20 minutes debugging this crap just because I forgot to put it here. You may or may not need it depending how you structure your app, but for me it seemed to simplify the pattern matching significantly.

The rest should be fairly self explanatory:

The ([^/]+) string will match anything but a slash character and save it in a variable ($1, $2 and $3 respectively). I then rewrite the URL the way it should look using the variables. The end effect is having the functionality of a long, ass-backwards query string combined with a simple and nice looking URL’s.

Also, this might be one of the shortest posts I have written on here in months. Enjoy the brevity while it lasts.

This entry was posted in technology. Bookmark the permalink.



5 Responses to Fancy Flat URL’s with htaccess

  1. freelancer SWEDEN Mozilla Firefox Windows Terminalist says:

    Nice tip. Just one addition for people who are not very familiar with .htaccess files; If you can place this in the Apache config instead (inside a Directory or DirectoryMatch section in httpd.conf, or another config file that’s included) you should. This is because if there is an .htaccess file, it is read every time a request is made, but if it’s in the config it’s only read once when the server is started.

    Reply  |  Quote
  2. Heh, I’ve got rewrite rules all over my server to clean things up. My main one has 8 entries at the moment. A lot of times when I see unnecessarily ugly URLs I wish people would do this more. Clean URLs are nice.

    You have to be careful with relative addresses, though. If you used an image located at “/img/me.jpg”, with the src set relatively to “img/me.jpg”, and your document was at,


    /blog.php?name=example&year=2009

    and it moves to,


    /blog/2009/example/

    The browser will go looking for it at,


    /blog/2009/example/img/me.jpg

    which will return 404 or something. It gets more complicated if the same document can be reached from different levels in the hierarchy.

    There are two solutions. The hackish way is to rewrite the stuff to not be as relative: put in the root slash. The more elegant solution is the base tag, which goes in the head.

    Reply  |  Quote
  3. Milos UNITED STATES Mozilla Firefox Windows Terminalist says:

    A very useful suggestion. Enjoyed (and was surprised by) the brief post as well. :) Thanks!

    Reply  |  Quote
  4. Jag INDIA Mozilla Firefox Windows says:

    hey thanks im fighting with so many shitty websites appeared first on google but they didn’t work and this worked very well. anyway we can avoid (RewriteBase /foo/) this or make it general ?

    Reply  |  Quote
  5. kakalot VIET NAM Google Chrome Windows says:

    I need to rewrite sub.domainname.com/rewrite-string/abc/def/ to sub.domainname.com/index.php/dir/controller/?var1=abc&var2=def.
    When user enter sub.domainname.com/rewrite-string/abc/def/ , browser will redirect to sub.domainname.com/index.php/dir/controller/?var1=abc&var2=def. I found this article and try but I can’t do that. Please some body help me!

    Reply  |  Quote

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>