Recursive. Custom web app development

Back to the blog

Recent Posts

Most Popular Posts

  1. Why you should be using a framework
  2. Dynamic methods in PHP
  3. Rewriting URLs with Apache's mod_rewrite and PHP
  4. Five easy things that make you a better web developer

About the Blog

Self portrait

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

a bird

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.

Download files (.zip)

Comments

Lazy duck said on 02 Nov 2007:
This post was rubbish with a bit of knowledge. The end.
Lazy duck said on 03 Nov 2007:
This post was average with liberal helpings of cheese covered . Great.
Jay said on 17 Apr 2008:
This post was very good. It gives you a starting point and helps you solve ONE very important part of web applications, how to make CLEAN URLs. I did not expect more, therefore I walk away satisfied.

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.
Jay said on 27 May 2008:
Unfortunately using this method however, in both a public_html directory and a public_html/subdirectory causes a 404 error send in the header.

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.
BillRead said on 06 Jun 2008:
This rocks -- I knew there must be an easy, elegant way of doing this re-write, but couldn't wrap my brain around it.
Bretticus said on 06 Sep 2008:
This is not rubbish, this is pure genius! This is the best way I HAVE EVER seen of doing this in my 8 years of web development!

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!
Matthew said on 17 Sep 2008:
The explode is a good idea. For some reason I've been using strpos of "/"...
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.
saravanan said on 21 Jan 2010:
Hi ,
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
sinisterMAC said on 16 Jul 2010:
Honestly. finally stuff you don't learn in books or school. I learned this on google.com :)
WimTibackx said on 25 Jul 2010:
After 2 hours of searching and finding the wrong answers, I found this. Thank you so much!
Web Development said on 02 Dec 2010:
i'm satisfied.It gives you a starting point and helps you solve ONE very important part of web applications, how to make CLEAN URLs.
thanks a lot for nice posting.