Back to the blog
Recent Posts
-
Dec 05
Twitter user streams with python
-
Nov 30
Fix Firefox 5+ font rendering in Windows
-
Aug 31
A bit of icon work
-
Jun 24
Your mobile OS can't really multitask...
-
Apr 27
Thoughts on Android and the HTC Dream
-
Feb 26
Announcing Twitterscribe: archive your tweets
Most Popular Posts
-
Why you should be using a framework
-
Dynamic methods in PHP
-
Rewriting URLs with Apache's mod_rewrite and PHP
-
Five easy things that make you a better web developer
About the Blog

I'm a web application developer in Melbourne, Australia. If you find anything useful, leave me a comment, and if you need web design, development, or accessibility and usability consulting, contact me! Cheers.
Twitter: joshsharp
Rewriting URLs with Apache's mod_rewrite and PHP
The start of an MVC framework
Sunday 28 Oct, 2007 03:15 PM
For those of you who aren't aware, Apache provides a very nifty module called mod_rewrite which (can you guess?) lets you rewrite URLs, with or without the end-client knowing. As I've mentioned before, this can be pretty handy. No longer must your URLs look like domain.com/folder/subfolder/file.php?some_id=23. Instead you can present your users with pretty URLs like domain.com/area/action/this_is_a_unique_identifier, and anything along those lines.
There are two main reasons why you'd want to do this:
- Accessibility for users: your users don't need to remember long GET parameters, or file extensions for that matter. URLs can become more relevant to the content and to the user.
- Accessibility for search engines: yes, this will help you quite a lot with The Google. You now have a far bigger chance to put your relevant keywords into the URL, which is one of the places they count the most.
So let's have a look at how you'd do this.
The .htaccess file
First off, if your hosting is not on a server running Apache, you're out of luck. Also, some shared hosting providers don't allow you to use .htaccess files, so if this doesn't work that may be why.
For everyone else, a .htaccess file contains directives to Apache pertaining to the folder you put it in, and all subfolders under it (unless you specify another .htaccess to override it). You can add directives about other modules besides mod_rewrite, but we won't be dealing with that.
So without further ado, the contents:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php?url=$1 [QSA,L]
</IfModule>
What this does
Line 1: Only follow these directives if mod_rewrite is loaded.
Line 2: Turn on the rewrite engine (to state the obvious).
Line 3 and 4: Only continue with rewriting if the requested file is not an existing directory (-d) or a file (-f).
Line 5: The first part of the RewriteRule is a regular expression which takes the entire URL. The second parameter tells Apache to pass this to index.php as the GET parameter url, without informing the user.
Fairly basic, right? This works for frameworks because typically the index page instantiates the framework app, which handles all actions. However if you're still dealing with separate PHP pages, you can use some further RewriteRules and regular expressions to point specific requests to different files.
Example: To rewrite requests to /blog/ to blog.php:
RewriteRule ^/blog/(.*)$ blog.php?url=$1
One index page to rule them all
If you're writing a framework, you'll probably want to use the single entry-point method where your index page farms out all requests to the controller. Here's how it might look:
<?php
include('app/classes.php');
include('app/app.php');
//init our app
$App = new App;
//grab the mod_rewrite url
$url = $_GET['url'];
//if the url is empty then the user has navigated just to root
if ($url == ''){
//start with default controller
$App->setController('home');
} else {
//grab each part of our URL - controller, action, and identifier
$path = explode('/',$url,3);
//pass these onto the app to handle
$App->setController($path[0],$path[1],$path[2]);
}
?>
Include all the classes you will need for the app, your controller, model and view superclasses, and then pass the URL to the app. Easy done.
If you decide to use this for your framework, you can download the .htaccess and index.php files below.
Comments
I applaud your brevity and 'getting-to-the-point-edness'. It is very UNIX-esque. I will stop using hyphenated-words now.
All the best.
Although the pages render fine.
I am trying to find a solution to this. Perhaps it is not your code but the way my server is configured, but I don't think this code will work universally out of the box when real subdomains and more than one .htaccess file are involved.
Think about it, no stupid rewrite rule to exclude your media files ("...what? You changed the stupid javascript file extension???") The rewrite conditions exclude and real and existing file or directory.
Passing the entire url to your script ensures that you have a baseline for determining what you really want to do with that url! For example, I can see alot of potential possibilities for handling bad links, or determining how end users are using your website, etc. To me, that translates to a custom algorithm that doesn't limit me to just pretty urls. No more specific ordinate position for passing data to the application from the link.
Genius!
There, I said something useful. Now I can say something totally unrelated.
I thought your site (this site) had a really interesting format, and I kind of liked it. But then I realized it looks like this because I just set firefox's font size 4 steps up for some reason. And I have a wide screen. It is like browsing the web in high definition or something.
Anyway, your site looks nice, especially zoomed in.
I have "http://xyz.com/event/4/viedo/" like that URL but i need to change [keyword] instead of "4" using htaccess.... becos that numaric value dynamically generated... and also want to change 16 url like above condition
please help me....... thanks
thanks a lot for nice posting.