我一直在浏览symfony2框架源代码。在他们的示例网站的htaccess文件中,我发现%{REQUEST_URI}::$1
编写如下:
RewriteCond %{REQUEST_URI}::$1 ^(/.+)(.+)::\2$
RewriteRule ^(.*) - [E=BASE:%1]
该规则上方的评论解释
以下内容将所有其他查询重写为前端控制器。该条件确保如果您使用Apache别名进行大规模虚拟主机托管,则会预先设置基本路径以允许正确解析app.php文件;它也适用于非混淆环境,提供安全,一刀切的解决方案。
但是,这并不能解释::$1
或::\2
。
他们是反向引用吗?如果没有,他们是什么?他们的目的是什么?
答案 0 :(得分:12)
我在Zend项目中遇到了几乎相同的htaccess文件,这是我的想法,希望它有所帮助。
htaccess文件(位于Zend项目目录,与index.php相同)说
RewriteCond %{REQUEST_URI}::$1 ^(/.+)(.+)::\2$
RewriteRule ^(.*)$ - [E=BASE:%1]
RewriteRule ^(.*)$ %{ENV:BASE}index.php [NC,L]
假设Zend安装在http://mydomain.tld/zend(我们稍后将其称为yourdomain)
我们正在请求yourdomain/mycontroller/myaction
因此%{REQUEST_URI}
将是/zend/mycontroller/myaction
。
注意$1
,这是htaccess context [1]中RewriteRule
指令中的模式“,在删除导致服务器到达的前缀后,最初将与文件系统路径匹配。当前RewriteRule
(例如app1/index.html
或index.html
,具体取决于指定的位置)“。
因此$1
将是mycontroller/myaction
。
%{REQUEST_URI}::$1
将是/zend/mycontroller/myaction::mycontroller/myaction
。
上述字符串将与^(/.+)(.+)::\2$
匹配。请注意,对于圆括号中的两个捕获组,即(/.+)(.+)
之前的::
,许多组合可以匹配。例如:
第1组:/z
第2组:end/mycontroller/myaction
或
第1组:/zend/mycontroller/myactio
第2组:n
之间的任何内容都是有效的匹配。事实上,最有趣的是
第1组:/zend/
第2组:mycontroller/myaction
(这是唯一一种情况)将反引用\2
(在::
之后)与第二组匹配。
在这种情况下,/zend/
将存储在环境变量BASE
中,这是第一个RewriteRule
所做的。 %1
引用RewriteCond
中第一个匹配的字符串/zend/
。
看看第二个RewriteRule
,很明显为什么需要这个。由于index.php
只能在/zend/index.php
中找到,我们需要在/zend/
前添加index.php
。
这里我们假设使用URL路径作为第二个RewriteRule
指令的替换。请参阅[1]并在RewriteRule Directive部分下搜索“要服务的资源的DocumentRoot-相对路径”。
以上所有内容都使查询字符串保持不变/不变。如何index.php
解析查询字符串(以及URI)。
最后是Zend安装在域根目录的情况。
%{REQUEST_URI}
将为/mycontroller/myaction
。$1
将为mycontroller/myaction
。 RewriteCond匹配的字符串为/mycontroller/myaction::mycontroller/myaction
。
这次(/.+)(.+)
中的第二个组永远不会匹配mycontroller/myaction
,因为第一个组的初始反斜杠后面至少需要一个字母,使第二个组与{{1}一样接近但不完全是ycontroller/myaction
所以不能匹配。
因此,不使用第一个mycontroller/myaction
。 {@ 1}} enviornment变量不会被设置,当第二个RewriteRule使用它时,它将只是空的。
<强>参考强>
[1] http://httpd.apache.org/docs/current/mod/mod_rewrite.html
答案 1 :(得分:6)
$1
中的%{REQUEST_URI}::$1
引用RewriteRule
指令的匹配字符串,即.*
中匹配的^(.*)
字符串。因此%{REQUEST_URI}::$1
扩展为用户提供的请求URI路径,以及当前内部URI路径和查询,以::
分隔。
模式^(/.+)(.+)::\2$
用于查找前缀(第一个捕获组),使剩余部分与::
后面的部分匹配(\2
是匹配字符串的后向引用该模式的第二个捕获组)。
如果找到这样的匹配,则前缀存储在环境变量BASE
([E=BASE:%1]
中,其中%1
引用先前成功的RewriteCond
模式的匹配字符串匹配)。