Geekpedia Programming Tutorials






Creating friendly URLs with mod_rewrite

This programming tutorial will teach you how to build search engine friendly URLs in PHP, which contain keywords and use HTML extensions. We are going to use the htaccess file and mod_rewrite module running on an Apache server.

On Sunday, March 5th 2006 at 06:16 AM
By Andrew Pociu (View Profile)
*****   (Rated 5 with 14 votes)
Contextual Ads
More PHP Resources
Advertisement
Creating search engine friendly URLs in PHP is easier than some may think. First you need to make sure your server can read .htaccess files, and that you have the mod_rewrite Apache module installed. The majority of webhosts have mod_rewrite active and are ready for rewriting URLs.

If you're running PHP on a Windows server (IIS), I'm afraid this method of rewriting URLs will not work for you.

Rewriting URLs with a query string


Most of the time you'll probably want to create URLs based on pages returned from a (MySQL) database. Say you have the following pages:



page.php?page=1

page.php?page=2

page.php?page=3




...and so on. Based on the
row ID passed through the page query string in the URL, you retrieve the content for that page. It's a common method for creating dynamic pages.

Now, how do you make these URLs look like:



page1.html

page2.html

page3.html




First you need to open .htacess and append the lines below. Or if you dont have a .htaccess file, you can create one.





RewriteEngine on

RewriteRule ^page(.*)\.html$ /page.php?&page=$1/ [L]



As you can see, we first turn on mod_rewrite, then we create a rule, which tells the RewriteEngine to parse the URLs of the form pageX.html and send the request to the server as page.php?page=X. In the browser window, the URL will remain static, meaning this will not act as a redirection when the page is visited by visitors or crawlers. For all they know, this is a static HTML page.

Don't forget to save the file and make sure it's located in the root of your website (or where page.php is located).



Now, believe it or not, all that's left to do is open the pages using the new URL. For example if you used page.php?page=1 you can now use page1.html. And the page value in the URL will still be retrieved in PHP using the same method - $HTTP_GET_VARS['page']

Note that the page will still be accessible through the query string form (page.php?page=1) but if you don't link to them, no one will know; it will be our little secret. All the visitors and the search engines will be using the friendly URLs instead.



In the example below you can see a method similar to what you used before to create links to your dynamic pages, retrieved from a database. You would probably put that line in a while loop to retrieve all the pages from a table.





<?php

echo "<a href='page.php?page=".$PageID."'>".$PageTitle."</a>";

?>



Now, you're simply going to form the URL as:





<?php

echo "<a href='page".$PageID.".html'>".$PageTitle."</a>";

?>

Rewriting URLs with multiple query strings


In terms of URL friendliness, the situation is worse when you have multiple values passed in the URL, because the url becomes long, and the search engines start giving less credit to that page. Fortunately, they can too be transformed into friendly URLs, easily. Say you have the following dynamic URLs, perhaps in these pages there are items that can be sorted differently, and you do that by passing values in the URL:



prod.php?type=1&sort=asc

prod.php?type=1&sort=desc

prod.php?type=2&sort=asc


prod.php?type=2&sort=desc



You probably get the point. Now how do we pass these values in a URL that looks static, such as:





prod1_asc.html

prod1_desc.html

prod2_asc.html


prod2_desc.html



Simply by using the following rule in the .htaccess file:





RewriteEngine on

RewriteRule ^prod(.*)_(.*)\.html$ /prod.php?&type=$1&sort=$2/ [L]

Passing keywords into the friendly URLs


Can it get any better? Yes, you can pass keywords in your URL, which not only helps the visitor figure out the content of the page, but also helps Google, MSN Search and the other search engines figure out what keywords define that page. This is extremely helpful if you have pages that contain articles, news, product reviews or similar content. You can either assign keywords for this content, that will be passed in the URL, or you can pass the title of the article/news/product in the URL. For instance, you have a page discussing the Chrysler 300M, and its title is plain and simple: Chrysler 300M.

You would normally link to this page by its database row ID:



review.php?car=1



Thanks to mod_rewrite you can make the URL look like:



review1_Chrysler-300M.html



What we're going to do, is we're going to pass the ID in the car attribute like we would normally do, but we're also going to pass another attribute, containing the title of the page. Something that the server will read as:



review.php?car=1&title=Chrysler-300M



In our review.php page, we will never read the title parameter from the query string, it's there just to provide the keywords; you're only interested in the car parameter . Hopefully this is clear to you, so now let's see what we need to do for getting this to work.



Obviously, we first need to create the rewrite rule as follows:






RewriteEngine on

RewriteRule ^review(.*)_(.*)\.html$ /review.php?&car=$1&title=$2/ [L]



That's it for the .htaccess file.

But there's one more thing we need to do inside every page that links to the new URL, which is very important: since the title attribute holds a string value we need to strip any special characters and spaces from it. For example when you retrieve a list of reviews from your database, you would want to create the URL as:





<?php

echo "<a href='review".$CarID."_".$CarTitle.".html'>".$CarTitle."</a>";

?>



But this would return a link such as review1_Chrysler 300M.html - notice the space in the filename. That's not so bad, but what if the title of the page is Chrysler 300M & Chrysler 300C. In that case the URL would look like review1_Chrysler 300M & Chrysler 300C.html - and that won't be accessible any longer, since "&" is a special character used for passing multiple values in the URL, and this would confuse the server.

The solution to this is simple: write a function which parses the title, and eliminates any special characters and even spaces (spaces are optional). And here's that function:





<?php

function StripUrl($title)

{

$title = str_replace("#", "sharp", $title);

$title = str_replace("/", "or", $title);

$title = str_replace("$", "", $title);

$title = str_replace("&amp;", "and", $title);

$title = str_replace("&", "and", $title);

$title = str_replace("+", "plus", $title);

$title = str_replace(",", "", $title);

$title = str_replace(":", "", $title);

$title = str_replace(";", "", $title);

$title = str_replace("=", "equals", $title);

$title = str_replace("?", "", $title);

$title = str_replace("@", "at", $title);

$title = str_replace("<", "", $title);

$title = str_replace(">", "", $title);

$title = str_replace("%", "", $title);

$title = str_replace("{", "", $title);

$title = str_replace("}", "", $title);

$title = str_replace("|", "", $title);

$title = str_replace("\\", "", $title);

$title = str_replace("^", "", $title);

$title = str_replace("~", "", $title);

$title = str_replace("[", "", $title);

$title = str_replace("]", "", $title);

$title = str_replace("`", "", $title);

$title = str_replace("'", "", $title);

$title = str_replace("\"", "", $title);

$title = str_replace(" ", "", $title);

return $title;

}

?>



Some of these characters are being stripped completely, and some are being replaced.

Now you can pass the title to this function before including it in the URL:





<?php

echo "<a href='review".$CarID."_".StripUrl($CarTitle).".html'>".$CarTitle."</a>";

?>



I hope this tutorial helped you create better looking, search engine friendly URLs. I've been using this method for a long time, in numerous websites and it worked perfectly.
Digg Digg It!     Del.icio.us Del.icio.us     Reddit Reddit     StumbleUpon StumbleIt     Newsvine Newsvine     Furl Furl     BlinkList BlinkList

Rate Rate this tutorial
Comment Current Comments
by Ruby on Thursday, March 30th 2006 at 04:08 PM

Awesome! I've been looking into url rewriting for a while now...

by necenzurat on Tuesday, May 16th 2006 at 09:16 AM

tnx man ther not so complicated :) but u forgot something, take a look here

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule ^index.html /index.php
</IfModule>

this will tel u if the mod_rewrite is on or of

by bs0d on Saturday, February 24th 2007 at 11:21 PM

If you simply wanted to strip the characters, you could use one line of code instead of 28, like this: $title = str_replace(array("&", "[", "%"), "", $title);

Note: I didnt type each character to strip, but you get the idea.

by John Greenbury on Sunday, April 15th 2007 at 03:46 AM

Andrei,

This is by far the best article available on how to generate multiple search engine friendly SEF urls from a data source like mySql via mod rewrite (mod_rewrite). I know because I have just spent a whole Sunday searching. Most don't show how to get html extension or use of key words (keywords). Yours does. Thank you thank you.

JG

by david on Saturday, October 6th 2007 at 11:01 PM

Thanks for this great article on creating friendly urls.. I made a slightly neater stripurl function so thought I should post it for others.

// used to strip the title of any bad characters so it can be made into page url
function StripUrl($title)

{

$badchars = array( \"#\", \"/\", \"$\", \",\", \":\", \";\", \"=\", \"?\", \"@\", \"<\", \">\", \"%\", \"{\", \"}\", \"|\", \"\\\\\", \"^\", \"~\", \"[\", \"]\", \"`\",\"\'\", \"\\\"\");
$title = str_replace($badchars, \"\", $title);
$title = str_replace(\"&\", \"and\", $title);
$title = str_replace(\"&\", \"and\", $title);
$title = str_replace(\"+\", \"plus\", $title);
$title = str_replace(\" \", \"_\", $title);
return $title;
}

by cocaboo on Tuesday, December 4th 2007 at 01:31 AM

This is a very helpful article - I looked for hours to see how page titles get into URLs. Is this the way most people do it, or is this just the easy way? (including the title in the query string)

What I'm wondering is this... If I am moving domains and all my old URLs are currently in search engines, how do I redirect to the new URL WITH the page title? So say this URL is found in Google: www.domain1.com?page.php?id=26 and I want to redirect that URL to www.domain2.com/page/26/My+Page+Title/ I won't be able to do this... I would have to redirect to www.domain2.com/page/26/ right? How do I get around this?

by Matt D. on Wednesday, December 26th 2007 at 03:46 AM

I've been looking through your different tutorials over the last week or so, and all I have to say is thanks! You're coding ideas have been a lot of help.

by Andrei Pociu on Sunday, March 16th 2008 at 06:48 PM

A new (shorter) function is available for stripping tricky characters:

http://www.geekpedia.com/code98_Standardize-string-to-a-strict-format.html

by Darko Martic on Tuesday, July 1st 2008 at 02:25 AM

Here's a nice simple tutorial I wrote:

http://www.martic.net/blog/development/programming/friendly-urls-the-easy-way/


Comment Comment on this tutorial
Name: Email:
Message:
Comment Related Tutorials
There are no related tutorials.

Comment Related Source Code
There is no related source code.

Jobs PHP Job Search
My skills include:
Enter a City:

Select a State:


Advanced Search >>
Latest Tech Bargains

Advertisement

Free Magazine Subscriptions

Today's Pictures

Today's Video

Other Resources

Latest Download

Latest Icons