3

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.

Olivier Pons
  • 15,363
  • 26
  • 117
  • 213
bcm
  • 5,470
  • 10
  • 59
  • 92
  • Why would you want `/testa.htm` to be "rewritten" to `/testa.htm`? This will absolutely cause an infinite loop – Alvin Wong Jul 23 '12 at 05:21
  • As mentioned, a starting point in trying to figure how to map the urls properly, and I didn't get the redirect as well for some reason... do you know how to solve the examples given (domain.com/?a=$1&b=$2 to domain.com/$1/$2)? So when the mapping happens... the url of the browser should not change as opposed to normal redirect. – bcm Jul 23 '12 at 05:32
  • I believe the ['mod-rewrite' tag wiki](http://stackoverflow.com/tags/mod-rewrite/info) has enough information – Alvin Wong Jul 23 '12 at 05:38
  • still struggling to get it working, even after looking through the wiki examples – bcm Jul 23 '12 at 07:38
  • I highly recommend setting `RewriteBase` if using `.htaccess` – Alvin Wong Jul 23 '12 at 10:08

3 Answers3

2

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)!)

Community
  • 1
  • 1
Olivier Pons
  • 15,363
  • 26
  • 117
  • 213
1

When want to write something like a range you should use []. e.g:

RewriteRule ^/test([a-zA-z0-9]+)\.htm$ /index.php?data=$1  [L]
undone
  • 7,857
  • 4
  • 44
  • 69
  • How to make this work without the equal sign, when $1 is in the middle of a string? – bcm Jul 23 '12 at 05:02
  • (I will put the [L] to be safe, but without the L, the page resolved once and for all for me, without the 500) – bcm Jul 23 '12 at 05:04
  • The `[L]` flag doesn't stop the full rewrite process. It only stop "this round", i.e. the rules below will not be done for the "rewritten URL", and the rewritten URL will get fed into another round of rewrite process again. Just like what's said in [this question](http://stackoverflow.com/questions/6797998/rewriterule-last-l-flag-not-working) – Alvin Wong Jul 23 '12 at 05:40
  • @AlvinWong sorry, I said what I wanted very badly:-( – undone Jul 23 '12 at 05:52
1

For me this was the simplest article I found which really helped me to figure out what I needed and worked in the end, so I'll share it here and try to use the terms which makes sense to me.

http://www.workingwith.me.uk/articles/scripting/mod_rewrite

RewriteRule ^page/([^/\.]+)/?$ index.php?page=$1 [L]

The right hand side (index.php?page=$1) is the destination which is hidden from the browser.

The left hand side is the mapping rule.

The variable parsed from the left - $1 need not be right at the end of the string and can be anywhere in the middle, for example, /CHECK/?VAR=$1MORETEXT or if there are more variables to parse from the left, it could be "/CHECK/?VAR=$1MORETEXT$2".

The "/?" is optional, if it is desired for the destination URL to not have a "/" at the end, don't include it and just end with the $ like ^page/([^/\.]+)$

The [L] is useful because it stops the htaccess from wasting time reading onwards once a matching Rule is found.

Olivier Pons
  • 15,363
  • 26
  • 117
  • 213
bcm
  • 5,470
  • 10
  • 59
  • 92