Mod Rewrite and Pretty URLs

20, May 2009

Contents

Today I pushed live the most recent changes to the site here. In my spare time recently, I've been working with Mod Rewrite to clean up the URLs (Uniform Resource Locators) within the site. Instead of linking posts by passing $_GET[] values through the URL, for example www.coreymaynard.com/blog/?post=11, they are now linked by title, so this post is now www.coreymaynard.com/blog/mod-rewrite-and-pretty-urls. This not only makes navigating the site easier, as the visitor is not distracted by an ugly URL in the Location Bar, but it also improves SEO (Search Engine Optimization). This results in a better page rank in Google searches, which means more visitors to your web site.

How to do it

For any of this to work you need to have mod_rewrite enabled on your server. The rewrite functions are all housed in a file called .htaccess. If you're used to Windows, that file name may seem odd - as there is no actual file name. However, it's origin is from the Linux world, where a . in front of a file signifies that it is a 'hidden' file - not visible in the standard file listings.

For this case, our .htaccess file is quite simple:

 <IfModule mod_rewrite.c>
 RewriteEngine On
 RewriteBase /blog/
 RewriteCond %{REQUEST_FILENAME} !-f
 RewriteCond %{REQUEST_FILENAME} !-d
 RewriteRule . /blog/index.php [L]
 </IfModule>

What Happened Here

Here's a quick break down of what the .htaccess file is doing:

  1. Checks to see if the server has the mod_rewrite.c module.
  2. Turns the Rewrite Engine on, to accept the following statements.
  3. RewriteBase sets the default directory to run all the URL rewrite commands on. That part of the URL is then stripped from the processing, and all other commands deal with the remaining URL.
  4. The next two lines tell the module that it should only rewrite the file if there is no existing file or directory that matches the file name passed in the URL.
  5. Here is where the magic happens. RewriteRule tells the module to change any URL that matches the RewriteCond requirements and direct it to /blog/index.php - the front page of the blog. The [L] stands for last - stop the rewrite process here.

So, to sum that all up, any URL that is passed to the site that does not match an existing file or directory is directed instead to /blog/index.php - but the URL itself does not change.

How to Use it

This means on the main blog page I need to pull that URL and get the extra information that has been passed thorough the URL as well. To do that, I need to pull the last directory from the URL so that I can query the database to find a matching blog post.

 $page = $_SERVER['REQUEST_URI'];
 $link = substr(strrchr($page, "/"), 1);

That little bit of PHP there will pull the URI (Uniform Resource Identifier) of the current page (including the directory that doesn't actually exist), and then put all the string right of the final slash into $link. $link can then be checked against the database to find the matching post with that link. From there it's just standard operating procedure.

As a Side Note

A very quick and dirty breakdown of the difference between URL and URI:

Comments

This space intentionally left blank.

Have Something to Say?

Questions? Comments? Concerns? Let me know what you’re thinking.

  • You can use Markdown formatting here.