.htaccess中的条件重定向取决于URL中的路径段数

.htaccess中的条件重定向取决于URL中的路径段数,.htaccess,mod-rewrite,.htaccess,Mod Rewrite,我想根据URL中路径段的数量执行.htaccess重定向。但是,如果检测到此条件,则不应再评估重写规则条件 假设我有如下URL: http://www.example.com/level1/level2/level3/...../levelx 我想使用RewriteRule进行重定向,具体取决于URL上的“级别”数量 例如,如果我有三个以上的“级别”(类似http://www.example.com/levels/level1/level2/level3/level4/../100)。我想重定

我想根据URL中路径段的数量执行
.htaccess
重定向。但是,如果检测到此条件,则不应再评估
重写规则
条件

假设我有如下URL:

http://www.example.com/level1/level2/level3/...../levelx
我想使用
RewriteRule
进行重定向,具体取决于URL上的“级别”数量

例如,如果我有三个以上的“级别”(类似
http://www.example.com/levels/level1/level2/level3/level4/../100
)。我想重定向到如下内容:
http://www.example.com/whatever.php?id=100
第页

但是,我会使用以下内容:

RewriteRule ^levels/(.+)/(.+)/(.+)/(.+)/(.+) basedir/whatever.php?id=$5
RewriteRule ^levels/(.+)/(.+)/(.+)/(.+)/(.+) basedir/whatever.php?id=$5

但这个问题的关键是创建一个条件,当原始URL上检测到的斜杠数量大于数量时(可能是可变的)。

.htaccess
中没有传统的“计数”方法。(您可以定义链接到外部程序的服务器端重写映射,但我认为这超出了这个问题的范围。)

如果路径段数量有限,则可以对响应进行硬编码。例如:

RewriteRule ^levels/$ /whatever.php?query=0 [R,L]
RewriteRule ^levels/[^/]*$ /whatever.php?query=1 [R,L]
RewriteRule ^levels/[^/]*/[^/]*$ /whatever.php?query=2 [R,L]
RewriteRule ^levels/[^/]*/[^/]*/[^/]*$ /whatever.php?query=3 [R,L]
RewriteRule ^levels/[^/]*/[^/]*/[^/]*/[^/]*$ /whatever.php?query=4 [R,L]
RewriteRule ^levels/[^/]*/[^/]*/[^/]*/[^/]*/[^/]*$ /whatever.php?query=5 [R,L]
RewriteEngine On
RewriteCond %{QUERY_STRING} ^1*$
RewriteRule ^levels/(.*)/(.*)$ levels/$1-$2?%{QUERY_STRING}1 [N,DPI]
RewriteRule ^levels/([^/]*)$ /whatever.php?query=%{QUERY_STRING} [R,L]
我会使用类似于:

RewriteRule ^levels/(.+)/(.+)/(.+)/(.+)/(.+) basedir/whatever.php?id=$5
RewriteRule ^levels/(.+)/(.+)/(.+)/(.+)/(.+) basedir/whatever.php?id=$5
捕获反向引用并不“计算”它们
$5
只保存第5个捕获子模式的值。这相当于硬编码。但是,请记住模式
+
也将捕获斜杠(即URL路径段)。因此,上面的正则表达式只“计算”前5个,而可能还有更多。还有9个反向引用的技术限制

变通办法 一种可能的解决方法是为源字符串中的每个斜杠(路径段)构建一个查询字符串(每次追加1个字符)

例如:

RewriteRule ^levels/$ /whatever.php?query=0 [R,L]
RewriteRule ^levels/[^/]*$ /whatever.php?query=1 [R,L]
RewriteRule ^levels/[^/]*/[^/]*$ /whatever.php?query=2 [R,L]
RewriteRule ^levels/[^/]*/[^/]*/[^/]*$ /whatever.php?query=3 [R,L]
RewriteRule ^levels/[^/]*/[^/]*/[^/]*/[^/]*$ /whatever.php?query=4 [R,L]
RewriteRule ^levels/[^/]*/[^/]*/[^/]*/[^/]*/[^/]*$ /whatever.php?query=5 [R,L]
RewriteEngine On
RewriteCond %{QUERY_STRING} ^1*$
RewriteRule ^levels/(.*)/(.*)$ levels/$1-$2?%{QUERY_STRING}1 [N,DPI]
RewriteRule ^levels/([^/]*)$ /whatever.php?query=%{QUERY_STRING} [R,L]
提出以下要求:

http://www.example.com/levels/lev1/lev2/lev3/lev4/lev5/lev6/lev7/lev8/lev9/lev10
将导致外部重定向到:

http://www.example.com/whatever.php?query=111111111
然后在
whater.php
中,计算
query
URL参数的长度,以确定级别数。因为我们严格计算斜杠的数量,“级别”的数量是count+1

解释 第一个
RewriteRule
通过循环内部重写(
N
标志)将原始URL路径中的所有斜杠重复替换为连字符(只是任意字符)。在每次迭代中,当斜杠被替换时,我们在查询字符串的末尾追加一个
1
。在本例中,需要使用
DPI
标志(
D
iscard
P
athname
I
information)来丢弃原始请求中附加的路径信息,否则这些信息将附加到重写的URL中-这是必要的,以防止无休止的重写循环(以及可能的服务器崩溃!)

一旦URL路径中的所有附加斜杠都被替换,第二个
重写规则将触发外部重定向。查询字符串(现在由格式为“11111”的字符串组成)作为
query
URL参数的一部分附加到重定向的URL

警告
  • 原始请求上不能有查询字符串。以上检查是否有一个或多个
    1
    。这也许可以根据需要加以调整
  • 以上“计算”的是斜线的数量,而不是严格地计算路径段的数量。因此,尽管最后一个路径段为“空”,但URL末尾的尾随斜杠仍会被计数。如果这是不可取的,则可以调整正则表达式。或者可以使用前置规则删除尾部斜杠