我在 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,这是RewriteRulehtaccess 上下文 [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