How to define url placeholder $1 for htaccess regex

bcm picture bcm · Jul 23, 2012 · Viewed 8k times · Source

I wrote the following in htaccess in the process of learning:

RewriteRule ^/test(a-zA-z)\.htm$ /test$1.htm

And test2.htm still gets mapped to test1.htm

I'm assuming the $1 is not being treated as the variable placeholder properly because $ is not escaped. What is the right way of writing this (so that for test purpose, test2.htm gets mapped to itself, test2.thm)

Ultimately, I'm trying to map something like:

domain.com/$1/$2 to domain.com/?a=$1&b=$2

or

domain.com/$1 to domain.com/?a=$1

I do not want the URL of the browser to change when the first url is mapped to the second. I know this is possible in C# Global.asax file (using routes.MapRoute), but not sure how to get this happening in php.

Answer

Olivier Pons picture Olivier Pons · Jul 23, 2012

Proceed by elimination, from the most complex to the less complex.

  • handle first 2 params, then QSA directive (important) to keep all GET variables, then L directive to stop all,
  • then handle first 1 param, then QSA directive (important) to keep all GET variables, then L directive to stop all,

That should work:

RewriteRule ^/([a-zA-z0-9]+)/([a-zA-z0-9]+)$ /?a=$1&b=$2 [QSA,L]
RewriteRule ^/([a-zA-z0-9]+)$ /?a=$1 [QSA,L]

Oh by the way:

And if that's not enough:

Two hints:

If you're not in a hosted environment (= if it's your own server and you can modify the virtual hosts, not only the .htaccess files), try to use the RewriteLog directive: it helps you to track down such problems:

# Trace:
# (!) file gets big quickly, remove in prod environments:
RewriteLog "/web/logs/mywebsite.rewrite.log"
RewriteLogLevel 9
RewriteEngine On

My favorite tool to check for regexp:

http://www.quanetic.com/Regex (don't forget to choose ereg(POSIX) instead of preg(PCRE)!)