我在 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
,这是RewriteRule
htaccess 上下文 [1] 中指令中的模式,“在删除将服务器引导到当前的前缀之后,最初将与文件系统路径匹配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
(之后)匹配。::
在这种情况下,/zend/
将存储在BASE
第一个RewriteRule
所做的环境变量中。The%1
指的是第一个匹配的字符串,RewriteCond
其中 is /zend/
。
看第二个RewriteRule
,很明显为什么需要这样做。由于index.php
只能在 中找到/zend/index.php
,我们需要/zend/
在前面添加index.php
。
在这里,我们假设使用 URL 路径作为第二个RewriteRule
指令的替换。请参阅 [1] 并在 RewriteRule Directive 部分下搜索“A DocumentRoot-relative path to the resource to beserved”。
以上所有内容都使查询字符串保持不变/不变。取决于index.php
如何解析查询字符串(以及 URI)。
最后是 Zend 安装在域根目录的情况。
%{REQUEST_URI}
将/mycontroller/myaction
。
$1
将mycontroller/myaction
。
RewriteCond 要匹配的字符串将是/mycontroller/myaction::mycontroller/myaction
.
这次第二组(/.+)(.+)
永远不会匹配mycontroller/myaction
,因为需要在第一组的初始反斜杠之后至少有一个字母,使第二组尽可能接近ycontroller/myaction
但不完全mycontroller/myaction
匹配,因此不可能匹配。
结果,第一个RewriteRule
没有被使用。BASE
环境变量不会被设置,当第二个 RewriteRule 使用它时,它会简单地为空。
参考
[1] http://httpd.apache.org/docs/current/mod/mod_rewrite.html