实际上 apache RewriteEngine 忽略了所有文件的存在,而只忽略了 URI 的修改。它仅在 .htaccess 的整个处理过程中 URI 不变时结束。
使用 /.htaccess 中的规则集:
RewriteEngine On
RewriteRule ^Test/(.*)$ Tests/$1 [L]
RewriteRule ^$ App/web/ [L]
RewriteRule (.*) App/web/$1 [L]
例如,我们使用查询 URL http://www.example.com/Test/ObjectTest.php检查。
运行 perdir RewriteEngine 1:
规则 1 会将其重写为 /Tests/ObjectTest.php。
运行 perdir RewriteEngine 2:
由于 URI 已更改,它会重新开始处理 /.htaccess。在本次运行中,规则 1 不再匹配,规则 2 也不再匹配。但规则 3 将匹配,因为 (.*) 匹配任何 URL,此处为 Tests/ObjectTest.php。我们得到 /App/web/Tests/ObjectTest.php。
运行 perdir RewriteEngine 3:
由于 URI 已更改,它会再次重新传递 /.htaccess。它再次匹配规则 3,我们得到 /App/web/App/web/Tests/ObjectTest.php。
我们有一个无限循环。
标志 [L] 忽略该标志之后的所有指令,但不忽略整个重写过程。
为了解决这个问题,我们必须添加 RewriteCond 的:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^Test/(.*)$ Tests/$1 [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^$ App/web/ [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (.*) App/web/$1 [L]
请参阅参考资料。