0

我正在尝试将所有请求路径重写为我的启动文件。像这样:

RewriteRule .* framework/init.php

除了,在这个框架中,有一些目录可以提供文件,而无需 PHP 处理请求。但是,我不想使用这些目录的实际路径,因为我希望能够让 PHP 路由器解释这些路径。因此,我想为这些目录设置别名。例如:

RewriteRule ^i/com/(\w+)/(.*)$ framework/components/$1/images/$2

现在的问题是,这两个重写规则都是单独工作的,但是当我尝试将它们结合起来时,事情就出错了。在别名重写发生后,它似乎重新评估了我的整个 .htaccess。以下是我尝试过的一些示例:

在某些条件下跳过 rewrite-everything 行:

rewriteRule ^i - [S=1]
RewriteRule .* framework/init.php
RewriteRule ^i/com/(\w+)/(.*)$ framework/components/$1/images/$2

不工作。看起来第二行被跳过了,然后第三行重写为第二行没有被跳过的条件,所以第二行执行。


使用独占 rewrite-everything 行:

RewriteRule (?!i).* framework/init.php
RewriteRule ^i/com/(\w+)/(.*)$ framework/components/$1/images/$2

相同的故事。


在异常行之后停止重写引擎:

RewriteRule ^i/com/(\w+)/(.*)$ framework/components/$1/images/$2 [L]
RewriteRule .* framework/init.php

不工作。


添加重写条件:

RewriteCond %{REQUEST_URI} ^(?!i)
RewriteRule .* framework/init.php
RewriteRule ^i/com/(\w+)/(.*)$ framework/components/$1/images/$2

请注意,当我删除两个 RewriteRules 之一时,上述所有示例都开始工作。我一直在寻找类似的问题,但他们都有我试图应用的解决方案。他们的问题和我的问题之间的一个区别是,我想将我的“特殊”目录重写为一个目录,当正常请求时,该目录会导致重写 init.php。谁能告诉我这是否可能,如果是的话,我错过了什么或没有得到什么?

4

2 回答 2

0

在做了一些研究之后,我发现重写引擎确实在重写后重新评估了一条路径:

处理重写的请求时,可能会再次遇到 .htaccess 文件或部分,因此可能会从头开始再次运行规则集。最常见的情况是,如果其中一个规则导致重定向(内部或外部)导致请求过程重新开始。

我应该使用 [END] 标志来完全停止重写引擎。

替代标志 [END] 不仅可用于终止当前轮次的重写处理,还可以防止任何后续的重写处理在每个目录 (htaccess) 上下文中发生。这不适用于由外部重定向产生的新请求。

然而,这个 [END] 标志是自 Apache 2.4 以来的新标志。

mod_rewrite 为 RewriteRule 添加了 [QSD](查询字符串丢弃)和 [END] 标志,以简化常见的重写场景。

所以结论是:除非我有 Apache 2.4,但我没有,否则无法完成。

编辑:我将留下这个答案“未选择”,因为当有人知道“旧”的做法时。

于 2012-05-02T15:17:34.530 回答
0

我今天找到了解决方案。我在^i-rule 匹配时设置了一个环境变量,然后检查是否稍后设置了该环境变量。如果是,我跳过.*-rule。像这样:

RewriteRule ^i/com/(\w+)/(.*)$ framework/components/$1/images/$2 [E=REWRITE:1,L]
RewriteCond %{ENV:REDIRECT_REWRITE} !1
RewriteRule .* framework/init.php

可能有点丑。但它在旧版本的 Apache 中就像一个魅力。

于 2012-05-04T20:02:05.707 回答