【问题标题】:Is mod_rewrite rewrite rule match depending on position in substitution?mod_rewrite 重写规则是否匹配取决于替换位置?
【发布时间】:2017-06-14 02:54:39
【问题描述】:

如果查询字符串包含 DEBUG 短语,我会尝试在 .htaccess 中回显正在重写的 URL 的当前状态:

RewriteCond %{QUERY_STRING} DEBUG
RewriteRule .+ echo.php?ip=%{REMOTE_ADDR}&url=$0&query=%{QUERY_STRING} [L]

我的 echo.php 脚本会回显预期的 URL。

但奇怪的是,当我将参数的顺序更改为:

RewriteRule .+ echo.php?url=$0&ip=%{REMOTE_ADDR}&query=%{QUERY_STRING} [L]

回显的 url 本身就是“echo.php”。 这是预期的行为吗?如果是,为什么?

【问题讨论】:

  • 您可以尝试添加[B] 标志来转义反向引用。这可能是未转义添加的 URL 的问题。无论如何,您都可以通过REQUEST_URI 环境变量获取URL,您不需要将其传递进去。QUERY_STRINGREMOTE_ADDR 也是如此。在 PHP 中,它们位于 $_SERVER 数组中,例如 $_SERVER['REQUEST_URI']。此外,如果您确实想以这种方式执行此操作,则需要添加ENV,所以%{ENV:REMOTE_ADDR},因为它与您正在访问的环境变量相同。但是请尝试使用[B] 标志来解决您的问题中提到的问题。
  • 添加 [B] 标志没有帮助。感谢您提供有关如何在 PHP 脚本中获取 URL 的提示,但我更感兴趣的是回答 mod_rewrite 如何工作以及为什么它会以这种奇怪的方式运行,而不是如何回显 URL。
  • @SuperDuperApps 您写道:“无论如何,您都可以通过 REQUEST_URI 环境变量获取 URL”,但是如果我有超过 1 次重写,我无法在重写过程中获取 URL 的当前状态规则,所以我需要按照我的方式传递它。
  • 您可以通过将LogLevel rewrite:trace6 添加到您的主配置然后检查错误日志(或 1 到 8 之间的另一个数字以获取更少或更多信息)来了解正在发生的事情。要在 PHP 中获取最后一个重写的 URL,请使用 $_SERVER['REDIRECT_URL']

标签: mod-rewrite url-rewriting


【解决方案1】:

当我测试时,我没有得到你所说的不同行为。当我以任何一种方式使用该规则时,在访问example?DEBUG 时,我都会得到echo.php 作为URL。这是因为.htaccess 中的规则会一直循环(因为整个目录处理在重写后会重新开始,包括重写规则),直到 URL 没有改变。因此,由于您匹配 .+,因此您将始终以 echo.php 结束,除非某些先前的规则妨碍并在达到您的规则之前结束该迭代的处理。

您可以通过将[END] 标志添加到停止任何进一步的mod_rewrite 处理的规则来证明这一点,然后您将获得您所期望的行为。您看到的差异一定是由于您之前的规则在某种程度上。

正如 cmets 中提到的,调试 mod_rewrite 的更好方法是使用 LogLevel rewrite:traceX 选项,X 是 1 到 8 之间的数字。3 是一个很好的起点,并从那里增加如果没有足够的信息。当您增加到 8 时,会有 很多 信息。您只能在主配置中启用它。见the documentation。确保再次将其关闭,因为所有日志记录都会影响性能。它不会干扰任何早期的LogLevel 指令。

【讨论】:

    猜你喜欢
    • 2012-07-22
    • 2010-12-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多