为什么要RewriteRule.和^(.*)$一样工作吗?

NRe*_*ngh 6 regex apache mod-rewrite pcre

考虑以下:

RewriteRule ^(.*)$ index.php/$1
Run Code Online (Sandbox Code Playgroud)

基于初出茅庐的菜鸟知识我的mod_rewrite的,这应该与整个URL部分匹配example.com/?query=string,然后用预先准备它index.php/,一般,这也正是发生了什么.

http://example.com/some/stuff -> http://example.com/index.php/some/stuff
Run Code Online (Sandbox Code Playgroud)

现在,考虑一下:

RewriteRule . index.php
Run Code Online (Sandbox Code Playgroud)

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

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

http://example.com/some/stuff -> http://example.com/index.phpome/stuff
Run Code Online (Sandbox Code Playgroud)

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

Mat*_*ple 1

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

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

当规则匹配时,就会发生替换。替换是完全替换,因此如果您不使用反向引用,$1那么原始模式中的任何内容都会丢失。在这种情况下,新路径就变成了index.php

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