.htaccess 在htaccess中::$1意味着什么?
我一直在浏览symfony2框架源代码。在他们示例网站的htaccess文件中,我发现.htaccess 在htaccess中::$1意味着什么?,.htaccess,mod-rewrite,apache2,.htaccess,Mod Rewrite,Apache2,我一直在浏览symfony2框架源代码。在他们示例网站的htaccess文件中,我发现%{REQUEST_URI}::$1编写如下: RewriteCond %{REQUEST_URI}::$1 ^(/.+)(.+)::\2$ RewriteRule ^(.*) - [E=BASE:%1] 这条规则上面的评论解释了这一点 下面将所有其他查询重写到前端控制器。该条件确保,如果您使用Apache别名进行大规模虚拟托管,则基本路径将被预先设置,以允许正确解析app.php文件;它也将在无别名的环境中
%{REQUEST_URI}::$1
编写如下:
RewriteCond %{REQUEST_URI}::$1 ^(/.+)(.+)::\2$
RewriteRule ^(.*) - [E=BASE:%1]
这条规则上面的评论解释了这一点
下面将所有其他查询重写到前端控制器。该条件确保,如果您使用Apache别名进行大规模虚拟托管,则基本路径将被预先设置,以允许正确解析app.php文件;它也将在无别名的环境中工作,提供一个安全、一刀切的解决方案
但是,这并不能解释::$1
或:\2
它们是反向引用吗?如果没有,它们是什么?它们的用途是什么?在
%{REQUEST\u URI}::$1
中的$1
引用重写规则
指令的匹配字符串,即^(.*)
中的*
的匹配字符串。因此,%{REQUEST_URI}:$1
被扩展到用户提供的请求URI路径,以及当前内部URI路径和查询,由:
分隔
模式^(+/.+)(.+)::\2$
用于查找前缀(第一个捕获组),该前缀使剩余部分与::
后面的部分匹配(\2
是对模式第二个捕获组的匹配字符串的反向引用)
如果找到这样的匹配,前缀将存储在环境变量
BASE
([E=BASE:%1]
,其中%1
引用了上一次成功的RewriteCond
模式匹配的匹配字符串)。我在Zend项目中遇到了几乎相同的htaccess文件,以下是我的想法,希望能有所帮助
htaccess文件(位于Zend项目目录,与index.php相同)说
假设Zend安装在(稍后我们称之为yourdomain)
我们正在请求yourdomain/mycontroller/myaction
因此%{REQUEST_URI}
将/zend/mycontroller/myaction
请注意,$1
,这是htaccess上下文[1]中的RewriteRule
指令中的模式,“在删除导致服务器使用当前RewriteRule
的前缀后,最初将与文件系统路径相匹配(例如,app1/index.html
或index.html
取决于指令的定义位置)”
因此$1
将成为mycontroller/myaction
和%{REQUEST_URI}:$1
将是/zend/mycontroller/myaction::mycontroller/myaction
上面的字符串将与^(/.+)(.+)::\2$
匹配。请注意,对于圆括号中的两个捕获组,即(/.+)(.+)
之前的::
许多组合可以匹配。例如:
第一组:/z
第2组:end/mycontroller/myaction
或
第一组:/zend/mycontroller/myactio
第2组:n
任何介于两者之间的匹配都是有效的。事实上,最有趣的匹配是
第一组:/zend/
第2组:mycontroller/myaction
这是唯一一种将\2
(在:
之后)反向引用到第二组a匹配的情况
在这种情况下,/zend/
将存储在环境变量BASE
中,这是第一个重写规则
的作用。%1
引用RewriteCond
中的第一个匹配字符串,即/zend//code>
查看第二个重写规则
,很清楚为什么需要这样做。由于index.php
只能在/zend/index.php
中找到,我们需要在index.php
前面添加/zend/
这里我们假设使用URL路径替代第二个RewriteRule
指令。请参阅[1]并在RewriteRule指令部分下搜索“要服务的资源的DocumentRoot相对路径”
所有这些都使查询字符串保持不变/不变。如何解析查询字符串(以及URI)取决于index.php
最后一个例子是Zend安装在域根目录。
%{REQUEST_URI}
将是/mycontroller/myaction
$1
将是mycontroller/myaction
RewriteCond要匹配的字符串将是/mycontroller/myaction::mycontroller/myaction
这次是(/。+)(。+)中的第二组
永远不会匹配mycontroller/myaction
,因为第一组的初始反斜杠后面至少需要有一个字母,使得第二组与ycontroller/myaction
一样接近,但不完全匹配mycontroller/myaction
,因此不存在匹配
因此,不使用第一个重写规则
。不会设置BASE
环境变量,当第二个重写规则使用它时,它将只是空的
参考资料
[1] ahhh,谢谢你的解释,我有一个想法,它是在计算它在系统中的“已安装”目录,相对于文档根目录。因此,如果你在“domain.com/”安装它,那么$1将是“/”而$2将是“空的”,但是如果你在“domain.com/install/directory/application/route”安装它,那么$1将是“/install/directory/”2美元将是“/申请/路线”如果你理解为什么,你能为我澄清一下吗?因为我不是100%确定他们为什么想要两个捕获组,你可以用一个例子来扩展你的答案吗?嗯,我想我误解了它在做什么,事实上,它似乎只是设置了一个环境变量,不管我打开了什么url,我创建了一个测试站点,它从来都没有出现过
RewriteCond %{REQUEST_URI}::$1 ^(/.+)(.+)::\2$
RewriteRule ^(.*)$ - [E=BASE:%1]
RewriteRule ^(.*)$ %{ENV:BASE}index.php [NC,L]