如何调试 mod_rewrite 规则?
这是一个“提出问题并自己回答”的案例,我将其发布以供任何遇到相同问题的人参考。
我在调试共享服务器上 .htaccess 文件中的 mod_rewrite 规则集时遇到了一些问题,我什至无法访问 Apache 错误日志。我找到了一种调试它们的巧妙方法,如下所示:
编写一个简短的脚本,仅打印出其查询字符串变量。例如,在 PHP 中:
',htmlentities(print_r($_GET,true)),'
'?>;
这就是您所需要的。
假设您将此脚本命名为“show.php”并将其放在 /public_html 中。然后在 .htaccess 文件中,确定规则集中您认为可能导致问题的点,并插入此规则:
RewriteRule (.*) /show.php?url=$1 [END]
效果与在常规程序中插入 PRINT 语句相同。它会让您知道 (a) 您已到达规则集中的该点,以及 (b) 当前重写的 URL 是什么。
它不像真正的调试工具那么快,但它可以完成工作。
如果您使用的是 Apache <2.3.9,则必须使用 [L]
而不是 [END]
。在这种情况下,需要注意的是您的规则集不应尝试将“/show.php”重写为其他任何内容。如果这是一个问题,您可以通过在最顶部添加此规则来修复它:
RewriteRule ^show.php$ - [L]
...只需记住在完成调试后将其删除!
This is a case of "ask a question and answer it myself", which I'm posting for the benefit of anyone who has the same problem.
I had some problems debugging a mod_rewrite ruleset in a .htaccess file on a shared server, where I couldn't even access the Apache error logs. I found a neat way to debug them, which is this:
Write a short script that simply prints out it's querystring variables. e.g. in PHP:
<?='<pre>',htmlentities(print_r($_GET,true)),'</pre>'?>
is all you need.
Let's say you name this script "show.php" and put it in /public_html. Then in your .htaccess file, identify the point in your ruleset that you think might be causing the problem, and insert this rule:
RewriteRule (.*) /show.php?url=$1 [END]
The effect is the same as inserting a PRINT statement in a regular program. It'll let you know that (a) You reached that point in the ruleset, and (b) what the current rewritten URL is.
It's not as flash as a real debugging tool, but it gets the job done.
If you're using Apache <2.3.9, you'll have to use [L]
instead of [END]
. In that case, something to look out for is that your ruleset should not attempt to rewrite "/show.php" to anything else. If that's a problem, you can fix it by adding this rule at the very top:
RewriteRule ^show.php$ - [L]
...Just remember to remove it when you're done debugging!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
其他可能性:
使用此在线 htaccess 测试器:
http://htaccess.madewithlove.be/
Other possibility:
use this online htaccess tester:
http://htaccess.madewithlove.be/
非常有帮助的见解。多年来,我一直试图弄清楚如何调试 mod_rewrite 规则,而无需具有 root 访问权限,也不必将规则放入 httpd.conf 中。这样就可以了!
PHP 中有一个小错误:
在这段代码中,print_r() 将 $_GET 中的所有内容输出到 stdout,然后返回值 true,htmlentities() 将其作为其第一个参数。 htmlentities() 还接收文字 true 作为其第二个参数,这是一个可选参数,告诉 htmlentities() 是否使用单引号和/或双引号。
我认为你的意图是:
这告诉 print_r() 格式化 $_GET 中的所有内容。将 true 作为第二个参数传递给 print_r() 告诉它不要将结果输出到 stdout,而是将结果放入字符串中并将该字符串作为 print_r() 的返回值返回。然后,htmlentities() 接收该字符串作为其一个输入参数,并进行适当的替换以强制浏览器按原样显示该字符串,而不是允许浏览器解释该字符串。 EG -
将被翻译为:
这将导致浏览器显示:
而不是以斜体显示单词“text”:
text
Very helpful insight. For years I've been trying to figure out how to debug mod_rewrite rules without needing to have root access and having to put the rules in httpd.conf. This does it!
You have one minor mistake in your PHP:
In this code, print_r() outputs everything in $_GET to stdout and then returns the value true, which htmlentities() picks up as its first argument. htmlentities() also receives the literal true as its second argument, which is an optional argument that tells htmlentities() whether or not to mess with single- and/or double-quotes.
I think what you intended was:
This tells print_r() to format everything in $_GET. Passing true as the second argument to print_r() tells it not to output the result to stdout, but instead to put the result in a string and return that string as print_r()'s return value. htmlentities() then receives that string as its one input parameter, and does appropriate substitutions to force the browser to display the string as is rather than allowing the browser to interpret the string. E.G. -
would get translated to:
which will cause the browser to display:
instead of displaying the word "text" in italics:
text