什么:: $ 1在htaccess中意味着什么?

时间:2013-05-26 17:59:26

标签: .htaccess mod-rewrite apache2

我一直在浏览symfony2框架源代码。在他们的示例网站的htaccess文件中,我发现%{REQUEST_URI}::$1编写如下:

RewriteCond %{REQUEST_URI}::$1 ^(/.+)(.+)::\2$
RewriteRule ^(.*) - [E=BASE:%1]

该规则上方的评论解释

  

以下内容将所有其他查询重写为前端控制器。该条件确保如果您使用Apache别名进行大规模虚拟主机托管,则会预先设置基本路径以允许正确解析app.php文件;它也适用于非混淆环境,提供安全,一刀切的解决方案。

但是,这并不能解释::$1::\2

他们是反向引用吗?如果没有,他们是什么?他们的目的是什么?

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.htmlindex.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模式的匹配字符串匹配)。