Apache RewriteRule and query strings

by Simon. Average Reading Time: about 2 minutes.

At first glance, the way the Apache mod_rewrite module handles query strings can be a little intimidating. mod_rewrite works by sitting on your server in a file called htaccess, and “catching” requests for URL‘s. It then checks these URL request against a series of rules and conditions you have set. If the request meets any of the rules and conditions, it applies then necessary changes to the URL, then reprocesses the request with the changes you have directed. Apache helpfully provides some RewriteCond documentation

The most common mistake people make when thinking of URL redirection with mod_rewrite, is they believe it creates something, or changes something. It doesn’t.

Here is a simple example, redirecting a page dependent upon its query string. The rewrite condition and rule looks like this:

RewriteCond %{QUERY_STRING} ^id=([0-9]*)$
RewriteRule ^page\.php$ http://www.example.com/page/%1.php [R=302,L]

The rewrite condition matches a numerical ID between 0 and 9. According to the official documentation, you would expect the following behaviour:

/page.php?id=1 -> http://www.example.com/page/1.php
/page.php?id=10 -> http://www.example.com/page/10.php

However, if you don’t append something new, then the original query is passed through by default. This results in the following:

/page.php?id=1 -> http://www.example.com/page/1.php?id=1
/page.php?id=10 -> http://www.example.com/page/10.php?id=10

If you want to discard the original query string you must append an empty question mark at the end of the rule; the query string not append or query string discard flag.

RewriteCond %{QUERY_STRING} ^id=([0-9]*)$
RewriteRule ^page\.php$ http://www.example.com/page/%1.php? [R=302,L]

Putting it all together, here’s a quick reference for dealing with query string in a RewriteRule.

Keep original query (i.e., the default behaviour)

RewriteRule ^page\.php$ /target.php [L]
# from http://www.example.com/page.php?foo=bar
# to http://www.example.com/target.php?foo=bar

Discard original query

RewriteRule ^page\.php$ /target.php? [L]
# from http://www.example.com/page.php?foo=bar
# to http://www.example.com/target.php

Replace original query

RewriteRule ^page\.php$ /target.php?bar=baz [L]
# from http://www.example.com/page.php?foo=bar
# to http://www.example.com/target.php?bar=foo

Append new query to original query

RewriteRule ^page\.php$ /target.php?bar=baz [QSA,L]
# from http://www.example.com/page.php?foo=bar
# to http://www.example.com/target.php?foo=bar&bar=foo

Dave Child has created a great mod_rewrite cheat sheet; a one-page reference sheet, listing flags for the RewriteRule and RewriteCond directives, list of server variables, a regular expression guide and several examples of common rules.

This article has been tagged

, , , , , , ,

Other articles I recommend

Apache .htaccess query string redirects

One of the most common tasks performed by Apache and htaccess is the manipulation of a URL and configuring a redirect for a specific page.

Enabling Search Engine Safe URLs with Apache and htaccess

An increasingly popular technique among websites and in particular, blogs, is the idea of making URLs search engine friendly, or safe, on the premise that doing so will help search engine optimisation. By removing the obscure query string element of a URL and replacing it with keyword rich alternatives, not only makes it more readable for a human being, but also the venerable robots that allow our page content to be found in the first place.

Configuring ColdFusion 8 with Apache

After installing ColdFusion 8 and Apache successfully you may still see an “HTTP 500 Internal Server Error” when navigating to a ColdFusion page. All is not lost, you simply need to configure, or check the configuration of Apache. Apache requires very little post installation modification, but it is always good practice to check the httpd.conf file to ensure that the ColdFusion “install” scripts did what they were supposed to do.