Take the 2-minute tour ×
Webmasters Stack Exchange is a question and answer site for pro webmasters. It's 100% free, no registration required.

I have the following code in my .htaccess file, which is working fine and using "pretty" permalinks to reroute everything back to /index.php, and using $_GET values to serve customized content based which URL was requested.

RewriteEngine on
RewriteBase /

RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([-\w.]+)$ index.php?page=$1 [R=302,L,QSA]

I'm just trying to get an understanding of how this code is working:

I get that the two RewriteCond's are there to avoid this behavior in the case that someone is requesting an actual file or directory. But my question involves how removing those two RewriteCond's causes a different error. If they are removed, and I request example.com/register, is the browser is redirected to:

example.com/index.php?page=index.php.

I can't see how these two things are related, so I was just wondering if anyone could explain why this happens? (I have R=302 set just for now so I can see where it's redirecting me to).

share|improve this question
add comment

1 Answer 1

up vote 3 down vote accepted

The pseudo-code translation of your .htaccess file would be something along these lines:

  • Line 1: In case we weren't previously planning to do anything special with URLs, we are now (RewriteEngine is an optional processing module and we're making sure its enabled).

  • Line 2: When we're talking about rewrite URLs, from here on append the path /, which in your case means on line 6 your rewrite URL would become: /index.php?page=$1.

  • Lines 4-5:

    • %{REQUEST_FILENAME} is a special server variable containing full local filesystem path to the file or script matching the request.
    • The -d switch is a test with a boolean result value, that returns true if the preceding value is an existing directory.
    • The -f switch is a test that returns true if the preceding value is an existing file.
    • The exclamation mark (!) is equivalent to the logic word NOT.

So in this instance, lines 4-5 are checking for the current request to make sure we're not referring to an existing file or directory, and then proceeding to execute the RewriteRule on line 6. If the conditions on lines 4 and 5 are not both true, then line 6 would be skipped.

  • Line 6: The string ^([-\w.]+)$ is a regular expression:

    • A dash (-) as the very first or very last character in the square brackets will be interpreted as a literal dash and not as a range instruction.

    • The backslash (\) is an escape character, without this this instead of a literal w character, the w would mean something else.

    • A dot (.) corresponds to a single character.

    • A plus (+) is one or more occurrences of whats inside the brackets [ ].

Now to summarize then on line 6:

If the request URL includes -w followed by any other character, then the RewriteRule will apply and change the URL to append the requested URL to index.php as a GET query parameter named page for the purposes of further processing through your .htaccess file.

By specifying a 302 redirect (R=302) however, this will trigger an HTTP 302 response and redirect the user's browser to this URL rather than keeping the RewriteRule a secret internal operation.

The L tells Apache this is the last rule to follow, and the rest of the .htaccess will now be ignored.

The QSA stands for Query-String-Append and tells Apache to add the page parameter to the existing query parameters, which otherwise would be replaced by default.

For more information about understanding regular expressions, see this. You can find detailed documentation for Apache's mod_rewrite module here. And a guide with some useful examples here.

share|improve this answer
    
Thanks for taking the time to answer! Very detailed and it explained a lot. I did know about the R=302 flag, I just had it set that way temporarily so I could see where it was being rewritten/rerouted. The links are great too, especially the last one. Thanks again. –  Joe Feb 7 at 16:50
    
Nicely detailed explanation (have a look at the edits for some formatting tips). –  dan Feb 7 at 16:52
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.