Click to See Complete Forum and Search --> : Apache RewriteRule Very Weird


FeelLikeANut
09-25-2007, 11:11 PM
I have this in an htaccess file.RewriteRule ^(.*)/?$ portal.php?action=$1And the PHP code for now simply echos $_GET['action']. But with the above rewrite rule, no matter what I type in the address bar, I *always* get "page.php".

If I change the rule to:RewriteRule ^([\w]*)/?$ page.php?action=$1then suddenly it works as expected. This also works:RewriteRule ^([\W]*)/?$ page.php?action=$1But this does not:RewriteRule ^([\w\W]*)/?$ page.php?action=$1

I'm completely confused. Am I missing something? Or is it time to reformat my comp?

TJ111
09-27-2007, 11:16 AM
I think you need a quick lookover of regular expressions. Read through this (http://www.regular-expressions.info), it only takes ~1 hr but makes regular expressions much more logical.

For example

RewriteRule ^([\w\W]*)/?$ page.php?action=$1
is looking for.
1.The beginning of the line, followed by
2. Any word character, or any non-word character (ie, any character), 0 or more times, as many times as possible, followed by
3.A forward slash and question mark at the very end of the line.

What exactly are you checking for and attempting to redirect?

FeelLikeANut
09-27-2007, 04:26 PM
2. Any word character, or any non-word character (ie, any character)I know. It was to demonstrate the il-logic that was happening. That matching \w works as expected, and matching \W works as expected, but matching . doesn't.

followed by a forward slash and question mark at the very end of the line.It's actually an optional slash. The question mark makes the slash optional.

What exactly are you checking for and attempting to redirect?I'm trying to take any URL (site.com/path/fubar) and redirect to a PHP page (portal.php?action=path/fubar). What I originally wrote was:RewriteRule ^(.*)/?$ portal.php?action=$1And what I got, no matter what address I type in, was:portal.php?action=portal.phpwhich I completely don't understand.

TJ111
10-01-2007, 09:40 AM
Oh your write about the slash, somehow I missed over it in my regular expression blurb:o . Mod_rewrite has given me plenty of headaches in the past for what should be a simple thing. You might have to create a more specific regular expression to extract just after the /.


RewriteRule ^[\w]*?.[\w]{3}(?:/([\w/.]+))?$ portal.php?action=$1

Thats probably not 100% correct, but I need to get to a meeting so I just threw it together.

Scleppel
10-01-2007, 01:52 PM
The problem with ^(.*)/?$ is that when mod_rewrite rewrites to the same directory the .htaccess file is in (ie. if you have /abc/.htaccess, rewriting from /abc/def to /abc/ghi will cause this problem, but rewriting to /zyx will not) it runs the .htaccess file again. This is because .htaccess files are processed very late, so Apache has to make a new sub request to itself to get the content that you now what. When you go to /abc it rewrites to /index.php?action=abc, then the mod_rewrite runs again, and it rewrites to /index.php?action=index.php and so on. Some configurations cause a 500 error when it loops, others (like yours) stop at a certain number.

To stop it looping, you can use
Options +FollowSymLinks

RewriteEngine On

# If it's not a real file
RewriteCond %{SCRIPT_FILENAME} !-f
# and it's not a real directory
RewriteCond %{SCRIPT_FILENAME} !-d
# rewrite to index.php
RewriteRule ^(.*)$ /index.php?action=$1 [QSA,L]

Or you can use
# If it's not a sub request
RewriteCond %{ENV:REDIRECT_STATUS} ^$
instead of those two RewriteConds. Or you can use all three.