URLs and User Experience

April 2nd, 2008

I really like URLs as a topic for user experience. Today, I found somebody else who also likes URLs and UI. Interestingly enough, he goes over what a good URL is but not how to create them in a working environment.

For anyone who’s programmed PHP, a URL like this is not uncommon: http://localhost/blog/index.php?page=photo&name=a-sunset-on-the-beach. It’s gross, unreadable, and for a non-programmer the parsing of the URL stops at the question mark. A URL is supposed to point, unambiguously, to a resource and that paradigm should not be broken when making pretty URLs. However, there does not need to be complete transparency from the resource indicator that the user sees to the resource that’s actually on the server. Consistency is important though. A URL should not ever go out of date and if it does change, proper redirections should be in place to aid users using older URLs.

Commonly, Apache’s mod_rewrite module is used to translate a pretty URL to an ugly one. For example, one might translate /blog/photo/a-sunset-on-the-beach to /blog/index.php?page=photo&name=a-sunset-on-the-beach. I agree that this is great for user experience but I do not think this is an optimal solution.

Why should we bother translating to a nasty URL when the nice URL comes to the server? Why not just pass PHP the nice URL and parse it as such. One could define a standardized structure for the URL:

/[base directory]/[category]/[item]

This URL would then be passed and parsed by PHP and the necessary PHP files would be included conditionally based on the [category] and [item] values.

Obviously, this approach requires a single point of entry into your PHP application where you parse the URL and dispatch to other PHP files as necessary. The first thing that needs to be done to get this working is to tell apache to pass the URL as is to PHP via an .htaccess file:

Options +FollowSymLinks
IndexIgnore */*
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . index.php

Within PHP, we need to define our base URL and then parse the incoming URL. Below is a sample index.php file which resides in the same directory as the .htaccess file created above:

<?php
 
// Tells that our base is /blog
$base_directory = array_filter(explode('/', '/blog'));
 
// Produces an array of our request vars.
$request_url = explode('/', $_SERVER['REQUEST_URI']);
 
// Remove the base directory from the request URL
$request = array();
$count = 0;
 
foreach ($request_url as $elem)
{
  if (array_search($elem, $base_directory) === FALSE)
  {
    $request[$count++] =  $elem;
  }
}
 
// Call the necessary controller object
include $request[0] . ".php";
 
?>

If we had passed the URL http://localhost/blog/photo/a-sunset-on-the-beach, we’d end up getting a $request variable that looked like this: array(0 => 'photo', 1 => 'a-sunset-on-the-beach'). The bottom line, which includes the file, is basically a controller which will use the $request array to generate what is needed and display the correct template to the browser.

I like this approach because it provides a write-once approach to URLs and allows the programmer to not think in terms of standard GET variables and start with a clean slate of pretty URLs. This example is quite rudimentary and to the point, which is why I recommend making this more robust before deploying it on a real site.

Leave a Reply