First I will tell you how to read the RewriteRule:
You start with the first (or next) RewriteRule entry:
RewriteRule ^(.*)$ index.php/$1 [L,QSA]
The first parameter is a regular expression that can match your requested URL. ^(.*)$ matches all and saves this “everything” inside the variable, which can be used later.
Only if there are previous RewriteCond entries are they evaluated as follows:
RewriteCond $1 !^(index\.php|resources|robots\.txt)
$1 is a link to the content matched inside the first parentheses of the RewriteRule. This compares with the second parameter, which is a regular expression with a few explicit names, as well ! denies expression, for example. this rule only allows a RewriteRule to be executed if the regular expression does not match. If this condition returns true, the following condition will be considered.
RewriteCond %{REQUEST_FILENAME} !-f
If the requested file name is not a real file on the hard disk, this condition is true.
RewriteCond %{REQUEST_FILENAME} !-d
If the requested file name is not a real directory, this condition is true.
Only if all these conditions are true (they are associated with AND), we return to the rewrite rule:
RewriteRule ^(.*)$ index.php/$1 [L,QSA]
The result of this overwrite step is defined as the second and third parameter. $1 used again, as is the content of the match, and the parameters determine that this rule, if it is initially agreed, will be the last rule (L) and that any query string defined in the rewrite target variable will be added to any query string in the original URL (QSA).
Criticism:
Regular rewriting for MVC frameworks should be as much as possible. All dubbing conditions must be evaluated for successful dubbing. The show will stop only if any of the RewriteCond returns false. Each request that is rewritten undergoes a lot of intense cpu tests. RewriteRule regex first, then the regular expression in the first RewriteCond, followed by two tests of the hard disk in the file system for the existence of the file.
On the other hand, the first RewriteCond seems unnecessary. It checks certain names and, if found, cancels the rewriting. "index.php" must be detected by the second RewriteCond, since it is an existing file (how rewriting will work if not). Everything that starts with “resources” will also be matched, but probably shouldn't for the same reasons: Existing resources will be found by the second RewriteCond. The latest file is "robots.txt". It is always useful to have one, possibly emtpy, if you want to avoid 404 when robots retrieve your site.
Since you are not changing anything in the query string, the [QSA] directive is not needed.
Improvements:
RewriteEngine on RewriteCond %{REQUEST_FILENAME} -f [OR] RewriteCond %{REQUEST_FILENAME} -d RewriteRule ^.*$ - [L] RewriteRule ^.*$ index.php [L]
The first RewriteRule will match the entire requested path. Two RewriteCond are associated with [OR], so the first RewriteCond, which returns true, will cancel further evaluation. The first RewriteCond checks to see if the requested file exists. If it exists, it returns true, and processing returns to the first RewriteRule. The target expression is "-", which means "do not overwrite". [L] stops further processing of rewriting rules. So at the end, for an existing file, we have only one regular expression and one file system test, and then this existing file will be sent to the browser.
If the file is not found, the first RewriteRule and RewriteCond will not start, so [L] will not stop the process. Thus, the second RewriteRule is executed. This is unconditional, and the regular expression is the same as before, matching everything and rewriting it to "index.php".
This rewrite will not invoke your index.php if any file exists, including /forum/login.php.
You can change the second to RewriteRule ^.*$ index.php/$0 [L] if you want to continue parsing $_SERVER['PATH_INFO'] instead of $_SERVER['REQUEST_URI'] .