【问题标题】:Why does RewriteRule . work the same as ^(.*)$?为什么要 RewriteRule 。工作方式与 ^(.*)$ 相同吗?
【发布时间】:2012-09-21 09:34:30
【问题描述】:

考虑以下几点:

RewriteRule ^(.*)$ index.php/$1

根据我对 mod_rewrite 的新手知识,这应该匹配 example.com/?query=string 之间的整个 URL 部分,然后在前面加上 index.php/,通常情况就是这样。

http://example.com/some/stuff -> http://example.com/index.php/some/stuff

现在,考虑:

RewriteRule . index.php

根据 Concrete5 CMS 当前更新的开发人员的说法,这完全一样。事实上,它似乎也在我的服务器上做到了这一点。

我的问题是,为什么第二个 RewriteRule 会产生相同的结果而不是类似的结果

http://example.com/some/stuff -> http://example.com/index.phpome/stuff

.不应该匹配一个字符然后替换为index.php字符串吗?这是在 Apache 2.2 上。

【问题讨论】:

    标签: regex apache mod-rewrite pcre


    【解决方案1】:

    RewriteRule ^(.*)$ index.php/$1 将匹配并使用捕获的文本创建一个新路径,并将最初请求的任何内容添加到 $1 所在的末尾。

    RewriteRule . index.php 匹配,因为它是一个未锚定的正则表达式。前面的正则表达式使用^$ 来锚定匹配,这意味着模式必须完全匹配,而这个不匹配,这意味着它将匹配字符串中的anywhere,所以任何带有任何字符都会匹配。因为 mod_rewrite 将每个测试视为一个正在运行的谓词,所以只要匹配,就会应用此规则。

    当规则匹配时,替换发生。替换是 complete 替换,所以如果你不使用像 $1 这样的反向引用,那么原始模式中的任何内容都会丢失。在这种情况下,新路径将变为 index.php

    因此 2 之间存在细微差别,因为第二个只是直接进入 index.php,而不在末尾添加最初请求的路径。 Concrete5 CMS 最有可能使用的是前端控制器,该控制器根据它直接从请求中提取的信息进行调度。由于这不是重定向重写,原始请求将被保留,以便仅使用它:将一些责任从 Apache 转移到应用程序代码手中,以减少对托管环境的依赖。

    【讨论】:

      【解决方案2】:

      左边的匹配没有替换,它只是搜索。您必须使用反向引用来替换/保留特定部分。

      【讨论】:

      • 文档说语法是RewriteRule Pattern Substitution [flags],不是吗?我仍然不清楚第二个示例中的“替换”如何产生它所做的结果。
      • 如果Pattern 匹配,那么它在它检查过的整个路径上执行Substitution
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-26
      • 2014-09-04
      • 2018-02-23
      • 1970-01-01
      • 2016-01-30
      • 1970-01-01
      相关资源
      最近更新 更多