While all what @Corey Henderson said makes absolutely perfect sense .. it is not 100% matches the reality.
Have only these 2 rules in your .htaccess (I know, this is a bit stupid example, but you may run into the same effect eventually when doing complex rewrites):
RewriteEngine On
RewriteRule (.*) /index.php?u=$1 [L]
You would think -- redirect ALL requests to index.php
. Flag [L]
is set so nothing to worry. Well -- apparently it is something to worry about, as after seeing [L] flag mod_rewrite goes to the next iteration (entering into a loop). Because we have rule that will always executed, we will have endless loop (well, there is setting in Apache config that controls it -- by default it is maximum 10 iterations). If limit is exceeded then you will see 500 Server Error message and this line in Apache's error.log: "Request exceeded the limit of 10 internal redirects due to probable configuration error. Use 'LimitInternalRecursion' to increase the limit if necessary. Use 'LogLevel debug' to get a backtrace."
The rewrite will stop if:
- No more rules to process
- External Redirect
[R=301]
- Explicit "nothing to rewrite" command is given (second parameter of
RewriteRule
-- destination should be -
.
- When rewriting to exactly the same URL as on beginning of iteration.
- Already mentioned "Request exceeded the limit of xx internal redirects".
So yeah .. the faster rewrite iteration will be interrupted (rule is on the top) the better it is.
When ordering your rules (when you have quite a few of them, not just 1-2-3) you may consider this logic (which rules goes on top):
- Rules for files/folders that you do not want to touch AT ALL, under any circumstances (process request as is, regardless of domain/protocol)
- Rules that do change domain (redirecting to
www.
for example) or protocol (forcing HTTPS) -- the quicker you do this the better it is (as if you do it too late it may already change URL from "nice" to real).
- Other important rules that may affect existing files/folders
- (Consider having this) "nothing to rewrite" for existing files/folders (see below, kind of #1 but for all existing resources)
- Other rules
- Catch all rule.
On vast majority of sites where rewriting URLs is in place you will not have more that 5-6 rules (default .htaccess files for most PHP frameworks I have seen + some products like WordPress have just "catch all" (if file/folder does not exist then rewrite request to index.php)).
Every website will have their own logic which makes the above list just a general recommendation, nothing more.
# Do not do anything for already existing files
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule .+ - [L]
My main point here is: If you have quite a few rules, consider inserting this kind of "nothing to rewrite" somewhere there to stop the iteration completely.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…