Reputation: 26281
I really struggle with regular expressions and mod_rewrite, and am trying to better understand. I have some rewrite script along with what I "think" is going on as comments. Please let me know if I have accurately described what is going on. Thank you
# don't do the following if Apache isn't configured with mod_rewrite
<IfModule mod_rewrite.c>
# self explanatory
RewriteEngine on
# Reference everything from Apache root (i.e. /var/www/html)
RewriteBase /
# Create a condition if statement and execute the following rules until the next condition is reached.
# This one checks if the request is a valid directory, a valid file, or a valid symbolic link
# The % symbol has something to do with backreference of the matched string in the condition.
RewriteCond %{REQUEST_FILENAME} -d [OR]
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -l
# Don't do anything (how?), and the [L] means to not match this condition anymore
RewriteRule ^ - [L]
# ^ and $ are the start and end of the patern.
# ([^/]+) takes all characters up to the first /,
# and then adds one more character because the + which is the /,
# and stores it as $1.
# It will only be matched, however, if a / follows plus 0 or 1 character due to the ?.
# Then redirect by adding ?p=$1 where $1 is the stored variable described above.
# The L flag means don't try to do it again, and QSA somehow adds the previous URL to it.
RewriteRule ^([^/]+)/?$ ?p=$1 [L,QSA]
# close if statement
</IfModule>
Upvotes: 0
Views: 61
Reputation: 143856
Rewrite conditions only affect the immediately following rule, which means the 3 conditions here:
RewriteCond %{REQUEST_FILENAME} -d [OR]
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -l
only get applied to the immediately following rule:
RewriteRule ^ - [L]
and it won't get applied to the rule at the bottom. The conditions essentially mean: any existing file, directory or symlink. The %
isn't a back-reference, it means a rewrite variable and in the case of %{REQUEST_FILENAME}
, it is the filename that would get mapped to by the URL-file mapping processor. So for example, if the URL is http://example.com/some/path/and/file.php
, the %{REQUEST_FILENAME}
would be something like /var/www/localhost/htdocs/some/path/and/file.php
, assuming your document root is /var/www/localhost/htdocs/
.
The:
RewriteRule ^ - [L]
rule matches everything (the ^
matches beginning of strings, which essentially means everything) and the -
means, don't change the URI, just pass it through. The [L]
flag stops rewritting. The reason this is important is the rewrite engine will loop through all the rules indefinitely (or until the internal recursion limit is reached) or until the URI stops changing. This stops rewritting completely because the input URI is unchanged.
The pattern:
^([^/]+)/?$
means: anything that isn't a /
, with an optional /
at the end. The ?
means the previous character is optional. So a request like: path/file.php
will not match because it has a /
in the middle. But path/
will match. The path
part is grouped using the ( )
characters and backreferenced using $
. So the result would be:
/?p=path
The QSA
flag appends any existing querystring, so a request like:
/path-name/?foo=bar
gets rewritten to:
/?p=path-name&foo=bar
Without QSA
, the &foo=bar
won't be there.
Upvotes: 1