Applying RewriteCond to Multiple RewriteRule in .htaccess

Print Friendly

Just a quick hints and tips update for today. On a number of my sites I have been using mod_rewrite to produce SEO friendly URLs. e.g. :

mysite.com/widgets/my-big-widget

instead of something like:

mysite.com/index.php?cat=4&function=show&prod=456

This is done using RewriteCond and RewriteRule statements in .htaccess. However, normally RewriteCond only applies to the RewriteRule immediately following it. This means we end up with horrible repetitive blocks of code in our .htaccess files. In this article I’ll show you how to rationalise this problem and shorten your code!

Typically, you could end up with something like (sorry about the line breaks!) in your .htaccess file. This example is just part of one of our files, and is used to strip trailing slashes from virtual SEO directories only – but it proves the point.

# External redirect to remove trailing slashes etc.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^./]+)/$ http://www.santweb.co.uk/$1 [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^./]+)/([^./]+)/$ http://www.santweb.co.uk/$1/$2 [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^./]+)/([^./]+)/([^./]+)/$ http://www.santweb.co.uk/$1/$2/$3 [L]
#

Clearly, this isn’t much fun, especially as things grow and become more complex. However, there is a less well known option of the RewriteRule statement, that tells apache to skip the next N number of RewriteRule statement. [S=N]. So instead of checking each time if the request is NOT a file AND is NOT a directory, we could do this:

#
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule .* - [S=3]
RewriteRule ^([^./]+)/$ http://www.santweb.co.uk/$1 [L]
RewriteRule ^([^./]+)/([^./]+)/$ http://www.santweb.co.uk/$1/$2 [L]
RewriteRule ^([^./]+)/([^./]+)/([^./]+)/$ http://www.santweb.co.uk/$1/$2/$3 [L]
#

In the above example, we are using the [OR] option (without the OR option, apache implicitly assumes that multiple RewriteCond statements are ANDed together) and reversing the RewriteCond tests. So we are now saying if the request IS a file OR a directory. The following RewriteRule then accepts anything (.*) and does not change it (-) and then skips the next 3 RewriteRule statements [S=3]. We have thus created a pseudo conditional block of RewriteRule statements.

We’ve shaved three lines of code, and made managing our .htaccess file that much easier. Enjoy!

Tags: , , ,

3 Responses to “Applying RewriteCond to Multiple RewriteRule in .htaccess”

  1. Kalenz March 25, 2012 at 5:28 pm #

    I can say that ‘you saved my life @@!’ thanks u so much!

  2. Nishant Agarwal January 7, 2012 at 6:46 am #

    Thanks. Really helpful.

  3. Vincent December 2, 2011 at 9:48 pm #

    I use the same code on my websites and it’s working very well. Good post!

Leave a Reply


4 + two =