nice URLs made easy

I was looking for a simple solution these days to implement nice urls. I searched and found lots of tutorials on this but none of them where simple enough for what I wanted to implement: the simplest nice URLs possible, so I started from scratch and with guide the official mod_rewrite reference and with lots of trial and error I came up with the following solution.

Prerequisites: access to the .htaccess file, mod_rewrite enabled and php supported on your server.

I put in .htaccess

Options +FollowSymlinks
RewriteEngine on
RewriteRule ^(.+)/(.+)/(.+) index.php?a=$1&b=$2&c=$3 [nc]
#RewriteBase /test/nice_urls

the first 2 lines are standard. They tell apache to start the mod_rewrite engine. The next line tells the rewrite engine to pick up any request of 3 parametes that is seperated with 2 slashes (/) and send it to the index.php assigning variables a,b,c the appropriate parameters. Last line was needed when I was playing around on my local development environment with XAMPP but apparently was not needed on my server so I comment it out (# in front, makes line a comment) but left it there for anyone that is using XAMPP
I put the following in the index.php just to see what each variable is assigned

echo "a = ".$_REQUEST["a"];
echo "b = ".$_REQUEST["b"];
echo "c = ".$_REQUEST["c"];

you can play around with this if you want.

This solution is good for 3 parameters in the URL. If you put less the apache would think you made an error (you can probably adjust the htaccess to account for less parameters). If you try put to put more then 3 parameters in it the 3rd variable and 2nd get assigned the last and one before the last parameters and the 1st variable get assigned everything else (you can probably adjust the htaccess to account for that too, I am not a mod_rewrite guru). But I thought about a more flexible solution that could handle any number of parameters passed using more php code instead of htaccess rules

Options +FollowSymlinks
RewriteEngine on
RewriteRule ^([a-zA-Z0-9/?+]+)$ index.php?a=$1 [nc]
#RewriteBase /test/nice_urls2

this time I assign everything in the url to the one and only variable "a" and inside the php file I exploded the variable to get all the parts.
the index.php contains

echo "a = ".$_REQUEST["a"].;
$params = explode("/",$_REQUEST["a"]);
echo "Your gave ". count($params). " parameters";
print_r($params);

again you can play around with this if you want. Try putting as many parameters as you want and see what happens.

If you want to get deeper in the mod_rewrite rules that I put in the htaccess file take a look at the guide the official mod_rewrite reference and the excellent mod_rewrite cheatsheet

Category: 

6 Comments

Your theory is nice, but the implementation has great limitations. Having previously used mod_rewrite exclusively to handle my url rewriting, I can say first hand that it's tough and not for the faint of heart.

A few weeks ago I saw the light when I found this article:

http://www.phpaddiction.com/tags/axial/url-routing-with-php-part-one/

The .htaccess file, which is almost identical to that of many of the popular blog software suites such as WordPress, simply checks to see if the file or directory exists; if not, it redirects to index.php

In my case, I created a handler.php page where all of my requests were sent. This php page uses the concepts in the remainder of the first part of that article to display content or redirect to other areas of my site based on the url. I'm much more familiar with PHP than I am with mod_rewrite and it eliminates the need to have complex .htaccess files. This method also does not rely on hard coding the number of available arguments to be passed via the url.

I don't get how you can call this easy, you're adding more complexity to the system than what is needed.
Also your rewrite rule will limit what you can have in the URL path since it only matches alphanumeric characters + some extra ones (the questionmark is also very wrong).

If you want to support nice-urls you should do this:

RewriteEngine On
RewriteRule .* /index.php

This will send the entire path to index.php, to access it use $_SERVER['REQUEST_URI'].

Welcome to the wonderfull world of rewrite it is the most loved and frustrating thing you will probably ever deal with so here are a few quick tips.
You should learn to use the super globals $_POST/GET etc and the world will rejoice!
Your missing a good security opertunity of restricting what the user can supply as a URL for your site (to stop XSS, SQL injection and more).

// only allow alphanumeric values
// and - which is a seperator
RewriteRule ^([a-z1-9-]+)/([a-z1-9-]+)/([a-z1-9-]+) index.php?a=$1&b=$2&c=$3 [nc]

This is a much better solution, restricted yes but why would you want to allow a URL like:

someurl/a'+or+'t'='t/auth=true/admin=true

And not to mention the SEO implications if you do it right, take a look at how wordpress does it.

Good luck

Great post. Is there anything explode() and implode() can't do?!

I've been doing something similar on http://bla.st/ however the next question is, what is the best way to decide what page to display? Currently I'm using nested switch statements with includes eg.
switch ($a[0]) {
case 'about': include('about.php'); exit(); break;
case 'contact': include('contact.php'); exit(); break;
case 'services':
switch ($a[1]) {
case 'web-design': include('web-design.php'); exit(); break;
case 'database': include('database.php'); exit(); break;
default: include('services.php'); exit(); break;
}
break;
}

(please forgive any syntax errors)
Any other suggestions?

http://bla.st/php/

wow nice article bro... keep going !!!!
i love it