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



我想根据URL中路径段的数量进行.htaccess重定向。然而,如果检测到该条件,则不应再评估RewriteRule条件。

假设我有这样的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

但这个问题的关键是创建一个条件,当在原始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]

我会使用这样的东西:

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

捕获反向引用并不"计算"它们。CCD_ 7简单地保持所捕获的第5个子模式的值。这相当于硬编码。但是,请记住,模式.+也将捕获斜杠(即URL路径段)。因此,上面的regex只"计算">前5个,而可能还有更多。还有9个反向引用的技术限制。

变通办法

一个可能的解决方法是为源字符串中的每个斜杠(路径段)生成一个查询字符串(每次附加1个字符)。

例如:

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

然后在whatever.php中,您将计算queryURL参数的长度,以确定级别的数量。由于我们严格计算斜杠的数量,因此"级别"的数量为计数+1。

解释

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

一旦URL路径中的所有附加斜杠都被替换,第二个RewriteRule就会触发外部重定向。查询字符串(现在由形式为"11111"的字符串组成)作为queryURL参数的一部分附加到重定向的URL。

注意事项

  • 原始请求上不能有查询字符串。以上检查一个或多个1。这也许可以根据需要进行调整
  • 上面"统计"了斜杠的数量,而不是严格意义上的路径段数量。因此,尽管最后一个路径段是"空的",但URL末尾的斜杠仍然会被计算在内。如果不需要的话,正则表达式可能会进行调整。或者可以使用预规则来删除尾部斜杠

最新更新