I'm trying to rewrite URLs as follows:
If module-name is missing or not allowed, it loads the home page of the website. No problems here.
The problem is that mod_rewrite isn't working as it should. I wrote these rewrite rules...
RewriteEngine On
RewriteRule ^([^/]*)/?$ handler.php?module=$1
RewriteRule ^([^/]+)/(.+)/?$ handler.php?module=$1&args=$2
...but instead of passing module-name as module to the handler, the rewrite engine passes the name of the script itself, handler.php. I tried with different regex in the last two days, but the result is always the same. I don't know what to do anymore!
The rewrite rules are inside an .htaccess, placed in the document root (together with handler.php), and I'm running xampp on an Ubuntu 11.10 64-bit machine.
Thanks in advance!
Yep, after rewrite occurs, it goes to next cycle instead of existing immediately as you would expect.
You need to alter your rule (or add separate condition) to ignore requests to handler.php
file. For example:
RewriteRule ^(?!handler\.php)([^/]*)/?$ handler.php?module=$1 [L]
RewriteRule ^(?!handler\.php)([^/]+)/(.+)/?$ handler.php?module=$1&args=$2 [L]
or with extra separate condition:
RewriteCond %{REQUEST_URI} !/handler\.php$
RewriteRule ^([^/]*)/?$ handler.php?module=$1 [L]
RewriteCond %{REQUEST_URI} !/handler\.php$
RewriteRule ^([^/]+)/(.+)/?$ handler.php?module=$1&args=$2 [L]
or even like that:
# do not touch requests to handler.php
RewriteRule ^handler\.php$ - [L]
# our rewrite rules
RewriteRule ^([^/]*)/?$ handler.php?module=$1 [L]
RewriteRule ^([^/]+)/(.+)/?$ handler.php?module=$1&args=$2 [L]
You can also go even this way (it really depends on your rewriting logic)
# do not do anything for requests to existing files
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule .+ - [L]
# our rewrite rules
RewriteRule ^([^/]*)/?$ handler.php?module=$1 [L]
RewriteRule ^([^/]+)/(.+)/?$ handler.php?module=$1&args=$2 [L]
A problem could be that existing file-names get rewritten as well. To avoid that, you can add:
RewriteCond %{REQUEST_FILENAME} !-f # ignore existing files
RewriteCond %{REQUEST_FILENAME} !-d # ignore existing directories
So for you it would be:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f # ignore existing files
RewriteCond %{REQUEST_FILENAME} !-d # ignore existing directories
RewriteRule ^([^/]*)/?$ handler.php?module=$1
RewriteCond %{REQUEST_FILENAME} !-f # ignore existing files
RewriteCond %{REQUEST_FILENAME} !-d # ignore existing directories
RewriteRule ^([^/]+)/(.+)/?$ handler.php?module=$1&args=$2