Server Fault is a question and answer site for system and network administrators. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

OK, after many search, trial and errors I've managed to create an .htaccess that do what I wanted (see explanations and questions after the code block):

<IfModule mod_rewrite.c>

RewriteEngine On

#1 If the requested file is not url-mapper.php (to avoid .htaccess loop)
RewriteCond %{REQUEST_FILENAME} (?<!url-mapper\.php)$

#2 If the requested URI does not end with an extension OR if the URI ends with .php*
RewriteCond %{REQUEST_URI} !\.(.*) [OR]
RewriteCond %{REQUEST_URI} \.php.*$ [NC]

#3 If the requested URI is not in an excluded location
RewriteCond %{REQUEST_URI} !^/seo-urls\/(excluded1|excluded2)(/.*)?$

#Then serve the URI via the mapper
RewriteRule .* /seo-urls/url-mapper.php?uri=%{REQUEST_URI} [L,QSA]


This is what the .htaccess should do:

  1. #1 is checking that the file requested is not url-mapper.php (to avoid infinite redirect loops). This file will always be at the root of the domain.
  2. #2 the .htaccess must only catch URLs that don't end with an extension ( --> catch | --> catch | --> don't catch) and URLs ending with .php* files (.php, .php4, .php5, .php123...).
  3. #3 some directories (and childs) can be excluded from the .htaccess (in this case /seo-urls/excluded1 and /seo-urls/excluded2).
  4. Finally the .htaccess feed the mapper with an hidden GET parameter named uri containing the requested uri.

Even if I tested and everything works, I want to know if what I do is correct (and if it's the "best" way to do it). I've learned a lot with this "project" but I still consider myself a beginner at .htaccess and regular expressions so I want to triple check it there before putting it in production...

share|improve this question
up vote 1 down vote accepted

2a will allow /some.dir/file because of the "." in the middle. You might want something like !\..[1,3], it would depend on your file/directory structure.

In the RewriteRules it's normal to use substitution matching instead of variable names:
RewriteRule (.*) /seo-urls/url-mapper.php?uri=$5 [L,QSA]
Note it's $5 because you currently have a match patterns all over your conditions.

share|improve this answer
I'm not sure I understand that $5... Can you please explain it to me a bit more? Thanks! – AlexV Jan 15 '11 at 14:17
In a Cond/Rule block you can create match blocks with parenthesis "()", then in the finale rule substitution you can pull those matches back in by using a "$" followed by the match number. Usually a Cond doesn't have any, then in the final Rule you use them to reorder bits and pieces of the URL, though it's very useful to pull in other bits and pieces. Your Conds have them all over the place, but they aren't actually used anywhere. – Chris S Jan 16 '11 at 1:24

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.