Elegant URL Rewriting

Please note: This post was written 5 years ago, which is an age in programming terms, so please don't treat this as gospel! I'll be updating all posts soon enough, but if you'd especially like this one to be updated let me know.

I ♥ htaccess

To me .htaccess files are black magic - one letter wrong and you get internal server errors bouncing around everywhere, so when it came to URL re-writing (more specifically removal of file extensions) I was a little tired of getting "Error 500" messages. But I finally managed to manipulate the dark magic that lyes deep within the realms of the kingdom of .htaccess file, and created a system whereby I made my server pass all URL arguments to a single file to play with. Here's what I did.

Firstly you're going to need to edit your .htaccess file, for my purposes I send all the info to my index.php file like so:

RewriteEngine On

<IfModule mod_rewrite.c>
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>

The code above simply ignores the path that was requested, and loads your index.php file. From there we can do implement some logic to decide what it is our users are after. To be able to understand the request we need to find out what the URL is, and to do that we will use some PHP to grab the URL, and then put the contents into an array like so:

$request = explode('/', $_SERVER['REQUEST_URI']); 
$args = array();
	
//Remove empty indexes
foreach($request as $r){
	if(!empty($r)){
		array_push($args, $r);
        }
}		

The above code simply creates an array where each index contains parts of the URL separated by a slash ('/'). We then look for any empty parts of the array to make sure we don't run in to difficulty later on. Now we need to think about when users visit the root directory of our site, when they do our array will be empty, so we need to cater for that by assigning our default page to our array with the following code:

//Allow no parameters
if(empty($args) || $args[0] == 'index.php'){ $args[0] = 'home'; }

Now for the next part we also need to consider page titles to use in out <title> sections, to do that we will look at making the slug more human-readable. We will implement that alongside the code that will deal with actually getting the physical files, and what we will do if a certain file doesn't exist.

if(file_exists($args[0] . '.php')){
	$page = str_replace("-"," ",ucfirst($args[count($args)-1]));
	include($args[0] . '.php');
}else {
	$page = '404';
	include('404.php'); //Keeps URL intact
}

So above we check to see if the file exists, and if it does we set the $page variable to a proper title - this isn't entirely necessary, but I found it useful later on. After that we simply include the file that was requested. But if the file doesn't exists, we include our 404 page to make sure our site doesn't simply throw an error.

Now in my case the included files would then query a database for content, but if you'd like you can do that directly in this file - instead of the include() statement, you could set up a database query there to ask for the page "with title" and go from there.

And with that you should have some fine looking URLs!

***

If you found this particularly useful and want to share the ♥ you can donate here.

***

No Responses



~ Comments are now closed ~

Get in touch here