24 May 2006

Web 2.0 URLs w/ Apache

(Yes, the term 'Web 2.0' is ridiculously overhyped.)

Let's say you have a Web application which takes two optional GET variables v1 and v2. Let's assume that v1 is always an integer and that v2 is always a character string. We'll also assume that a DirectoryIndex index.php directive has been applied:

http://www.example.com/somedir/index.php?v1=27&v2=hello

And let's say your application has an administrative interface in an 'admin' subdirectory:

http://www.example.com/somedir/admin/admin.php

Try putting the following in your Apache configuration (this assumes that mod_rewrite is enabled):

RewriteEngine on
RewriteBase /somedir
RewriteRule ^admin - [L]
RewriteRule ^(\d+)/([a-z]+)/?$ /somedir/index.php?v1=$1&v2=$2 [L]
RewriteRule ^([a-z]+)/(\d+)/?$ /somedir/index.php?v1=$2&v2=$1 [L]
RewriteRule ^(\d+)/?$ /somedir/index.php?v1=$1 [L]
RewriteRule ^([a-z]+)/?$ /somedir/index.php?v2=$1 [L]

(You could put this in an .htaccess file if your Apache configuration applies an AllowOverride FileInfo directive to this part of your content area.)

You application should now be accessible by any of the following URLs:

http://www.example.com/somedir/hello/27/
http://www.example.com/somedir/27/hello/
http://www.example.com/somedir/hello/
http://www.example.com/somedir/27/
http://www.example.com/somedir/

The first and second URLs should set both variables, the third URL should set v2 only, the fourth should set v1 only, and the fifth should set neither (the fifth URL should still run the application because of the DirectoryIndex index.php directive).

Of course, it doesn't have to be '27' and 'hello'--it can be '42' and 'foobar', or whatever.

And your admin interfaces should still be accessible as before (the dash in the 'admin' RewriteRule means 'no alteration').

In the example I've used PHP as the hypothetical Web application, but the language doesn't matter--this is all Apache magic. But if you want to test this with some PHP code, try this in index.php:


header('Content-type: text/plain');
$v1 = '';
$v2 = '';

if ( isset($_GET['v1']) && $_GET['v1'] ) {
$v1 = $_GET['v1'];
printf("v1 is %s\n", $_GET['v1']);
}
else {
printf("v1 not set\n");
}

if ( isset($_GET['v2']) && $_GET['v2'] ) {
$v2 = $_GET['v2'];
printf("v2 is %s\n", $_GET['v2']);
}
else {
printf("v2 not set\n");
}

No comments: