.htaccess
文件中调试RewriteRule和RewriteCond语句时会遇到问题。其中大部分人使用共享托管服务,因此无法访问根服务器配置。他们不能避免使用.htaccess
文件进行重写,并且像许多回答者建议的那样,无法启用“RewriteLogLevel”。此外,有许多.htaccess
特定的陷阱和限制没有得到很好的涵盖。对于大多数人来说,设置本地测试LAMP堆栈涉及太多的学习曲线。
因此,我的问题是如何建议他们自己调试规则。我在下面提供了一些建议。欢迎提出其他建议。
Understand that the mod_rewrite engine cycles through
.htaccess
files. The engine runs this loop:do execute server and vhost rewrites (in the Apache Virtual Host Config) find the lowest "Per Dir" .htaccess file on the file path with rewrites enabled if found(.htaccess) execute .htaccess rewrites (in the user's directory) while rewrite occurred
So your rules will get executed repeatedly and if you change the URI path then it may end up executing other
.htaccess
files if they exist. So make sure that you terminate this loop, if necessary by adding extraRewriteCond
to stop rules firing. Also delete any lower level.htaccess
rewrite rulesets unless explicitly intent to use multi-level rulesets.Make sure that the syntax of each Regexp is correct by testing against a set of test patterns to make sure that is a valid syntax and does what you intend with a fully range of test URIs. See answer below for more details.
Build up your rules incrementally in a test directory. You can make use of the "execute the deepest
.htaccess
file on the path feature" to set up a separate test directory (tree) and debug rulesets here without screwing up your main rules and stopping your site working. You have to add them one at a time because this is the only way to localise failures to individual rules.Use a dummy script stub to dump out server and environment variables. (See Listing 2)If your app uses, say,
blog/index.php
then you can copy this intotest/blog/index.php
and use it to test out your blog rules in thetest
subdirectory. You can also use environment variables to make sure that the rewrite engine in interpreting substitution strings correctly, e.g.RewriteRule ^(.*) - [E=TEST0:%{DOCUMENT_ROOT}/blog/html_cache/$1.html]
and look for these REDIRECT_* variables in the phpinfo dump. BTW, I used this one and discovered on my site that I had to use
%{ENV:DOCUMENT_ROOT_REAL}
instead. In the case of redirector looping REDIRECT_REDIRECT_* variables list the previous pass. Etc..Make sure that you don't get bitten by your browser caching incorrect 301 redirects. See answer below. My thanks to Ulrich Palha for this.
The rewrite engine seems sensitive to cascaded rules within an
.htaccess
context, (that is where aRewriteRule
results in a substitution and this falls though to further rules), as I found bugs with internal sub-requests (1), and incorrect PATH_INFO processing which can often be prevents by use of the [NS], [L] and [PT] flags.
还有其他的评论或建议吗?
代码清单1 -- phpinfo
<?php phpinfo(INFO_ENVIRONMENT|INFO_VARIABLES);