Using mod_rewrite on websites is fairly straightforward and can create some lovely looking URL structures. Instead of having a URL that contains lots of odd looking parameters like this:
http://www.example.com/example.php?parameter1=value1¶meter2=value2
You can use a .htaccess file to rewrite the URL on the server side in order to shorten this to something like this:
http://www.example.com/p-value1
In this occasion the value of parameter2 will always be value2 so we can just include that in the rewrite rule, which would look something like the following. $1 is a back-reference to the first parenthesized value matched in the RewriteRule.
RewriteRule ^p-(.*)$ /example.php?parameter1=$1¶meter2=value2 [L]
Remember to turn ensure that the FollowSynLinks directive is enabled and that the rewrite engine is turned on before starting your rewrite rules. FollowSynLinks should have been enabled by your server administrator, but you can include here just in case they haven't.
Options +FollowSymLinks
RewriteEngine On
You can also make sure that mod_rewrite is actually installed by enclosing all of this in an if statement. This will stop the server throwing an error if you don't have mod_rewrite.
<IfModule mod_rewrite.c>
Options +FollowSymLinks
RewriteEngine On
</IfModule>
What PHP sees on the server side is exactly the same as normal so you can retrieve the parameters with a standard $_GET lookup.
However, the default behaviour of forms messes this up. Lets say that we had a search page that we created a rewrite rule so that it read like this:
http://www.example.com/s-value1
This redirects to the page search.php and passes any parameters to that page. The problem here is if we call the same page through a form. Here is an example search form.
<form action="search.php" method="get">
<input type="text" name="q" value="" />
<input type="submit" name="s" value="Search" />
</form></code>
When this is run with the string "test" the URL looks like this.
search.php?q=test&s=Search
This is the default browser behaviour, but it still messes up the nice URL structure created previously. There is a way to fix this. Have a look at the following .htaccess file.
<IfModule mod_rewrite.c>
Options +FollowSymLinks
RewriteEngine On
RewriteCond %{REQUEST_URI} /search.php$
RewriteCond %{QUERY_STRING} ^q=([A-Za-z0-9\+]+)&s=Search$
RewriteRule ^(.*)$ /s-%1? [R=301,L]
RewriteRule ^s-(.*)$ /search.php?q=$1&s=Search&a=1 [L]
</IfModule>
Here we are using the RewriteCond directive which allows us to test for certain conditions. In this case we have two conditions.
RewriteCond %{REQUEST_URI} /search.php$
RewriteCond %{QUERY_STRING} ^q=([A-Za-z0-9\+]+)&s=Search$
The first condition allows us to only run the rule on the page search.php. This stops any annoying confusion if we want to pass a similar query string to a different page. The second condition allows us to test the query string to see if it contains the parameters we are looking for. The %{QUERY_STRING} bit is a reference to the actual query string passed, minus the question mark at the beginning. In this case we want to trap the parameter q with any value and the parameter s with the value of Search. The dollar sign at the end is very important, but I'll come back to that.
The first rewrite rule redirects the page search.php to the URL /s- and whatever the query string was. The %1 is a back-reference to the first parenthesised value matched in the most-recently-matched RewriteCond.
RewriteRule ^(.*)$ /s-%1? [R=301,L]
We then also need to include a rewrite rule that will recognise the new URL and act on it. However, want we don't want to do is confuse the server and put it into an endless loop, which is quite easy since we are redirecting from search.php to search.php. So what we do is include the parameter "a" at the end of our rewrite rule with the value of 1.
RewriteRule ^s-(.*)$ /search.php?q=$1&s=Search&a=1 [L]
Going back to the second rewrite condition above we included a dollar sign at the end of the rule. This meant that the string had to end there, so if we include anything else after the end of the query string the rewrite condition will return false. So although we don't actually use the a in our script it is needed there to stop the server going into an infinite loop of redirects.
For more information on mod_rewrite and other .htaccess examples have a look at the excellent tutorial at Ask Apache.
Comments
Submitted by jammarlibre on Sun, 08/03/2008 - 05:30
PermalinkSubmitted by Rosina on Sun, 08/03/2008 - 22:49
PermalinkSubmitted by Hannes on Sat, 08/30/2008 - 12:00
PermalinkSubmitted by Dennis on Thu, 12/04/2008 - 20:52
PermalinkSubmitted by Mark on Thu, 02/19/2009 - 00:20
PermalinkSubmitted by Mark on Thu, 02/19/2009 - 00:22
PermalinkSubmitted by giHlZp8M8D on Fri, 02/20/2009 - 10:08
PermalinkAdd new comment