views:

31

answers:

1

Hi, I'm having a small problem with mod_rewrite

I have the following in my .htacces:

Options +FollowSymlinks
RewriteEngine on
RewriteRule ^(.+)\.htm$ index.php?name=$1 [NC]

This is my index.php file:

<?php echo $_GET['name']; ?>

This works great for the following url:

www.mySite.com/this is an example.htm

this would display "this is an example"

What i'm trying to do however, is get it to do the same, without the .htm extension: for example:

www.mySite.com/this is an example

Any ideas?

(dont think it's relevant but i'm using xampp to test this)

+1  A: 

You can just make the extension optional in your rewrite rule:

RewriteEngine on
RewriteRule ^(.+)(\.htm)?$ index.php?name=$1 [NC]

Note that this is pretty much the equivalent of

RewriteRule ^(.+)$ index.php?name=$1 [NC]

which means that any URL other than going directly to www.mySite.com will redirect to index.php. If you have more specific rules, they should appear before this one.

Update: Like I was saying, this rule will match essentially all URLs on www.mySite.com -- including index.php! Therefore, when you go to www.mySite.com/this is an example, the following happens:

  1. ^(.+)(\.htm)?$ matches "this is an example"
  2. mod_rewrite translates that to /index.php?name=this is an example
  3. mod_rewrite redirects to /index.php?name=this is an example
  4. After the redirection, mod_rewrite tries to evaluate rules again.
  5. ^(.+)(\.htm)?$ matches "index.php"
  6. mod_rewrite translates that to /index.php?name=index.php, clobbering the previous value for the name querystring parameter

In order to prevent the second redirection (specifying [L], or last, doesn't work, because after the first redirection rules are reapplied), you can use a RewriteCond to specify when to redirect:

RewriteCond %{REQUEST_URI} !^index\.php
RewriteRule ^(.+)(\.htm)?$ index.php?name=$1 [NC]

This tells mod_rewrite to not apply the rule if the request URI (the part of the URL after the domain) starts with index.php.

You should take a look at the other rewrite conditions that you can specify. For example, you probably don't want users to be redirected if they browse directly to another php file, either, so you can specify that in your RewriteCond too:

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !^index\.php
RewriteRule ^(.+)(\.htm)?$ index.php?name=$1 [NC]

Which reads "if the request is not a file and the request is not index.php, redirect to index.php".

Daniel Vandersluis
thanks for your speedy response. when i try this though, the output on my page is "index.php" instead of "this is an example"
alex
Add [L] to the rule.
Wrikken
still didn't work -this sort of does RewriteRule ^([^/\.]+)/?$ index.php?name=$1 [L] - however, if i put "www.whatever.com/this is a test.htm" it blows up...?
alex
excellent! thanks for your help!
alex