重写dynamicurl

我试图重写1个dynamicurl到另一个dynamicurl如下;

/category?category=News to /categorysearch/result/?q=news 

我想知道如果有人有一个想法如何可以在htaccess中完成?

谢谢。

所以最后的EDITED解决方案是(对于你的链接.htaccess):

 RewriteCond %{REQUEST_FILENAME} ethical [NC] RewriteCond %{QUERY_STRING} (^|&|%26|%20)ethical(=|%3D)([^&]+) [NC] RewriteRule .* /catalogsearch/result/?q=%3 [L,R] 

如果我在这个现在的问题中使用“类别”这个术语:

 RewriteCond %{REQUEST_FILENAME} category [NC] RewriteCond %{QUERY_STRING} (^|&|%26|%20)category(=|%3D)([^&]+) [NC] RewriteRule .* /categorysearch/result/?q=%3 [L,R] 

但是第一个更清楚,单词分类并没有到处使用。 如果你想添加小写转换,我们甚至可以这样做:

 # outside of a Directory section RewriteMap lowercase int:tolower # in a Directory section (not a .htaccess) RewriteCond %{REQUEST_FILENAME} category [NC] RewriteCond %{QUERY_STRING} (^|&|%26|%20)category(=|%3D)([^&]+) [NC] RewriteRule .* /catalogsearch/result/?q=${lowercase:%3} [L,R] 

但是正如最后一个用tolower所说的那样,在.htaccess中无法工作 – 无论如何.htaccess对于演出来说都是不好的,实际上,你应该考虑设置AllowOverride None并把所有的东西都放在一个VirtualHost中。 而好的东西,如rewriteMaps不能在.htaccess文件上工作。

所以现在我将解释规则。 首先,你的情况中的主要问题是“?”query_string ,而不是请求的文件名 。 而且大多数rewriteRules都试图处理所请求的文件名。 所以我首先检查一下目标文件名:

 RewriteCond %{REQUEST_FILENAME} category [NC] 

然后我们要处理查询字符串(问号后的所有内容)。 我们本来可以写一些比较简单的东西:

 RewriteCond %{REQUEST_FILENAME} category [NC] RewriteCond %{QUERY_STRING} ^category=(.+) [NC] RewriteRule .* /catalogsearch/result/?q=${lowercase:%1} [L,R] 

要捕获所有内容?category =在RewriteRule的变量%1中。 但是QUERY_STRING参数有几个问题,让我们尝试一下:

  • 这个参数还没有对url进行解码
  • 类别可能不是参数列表中的第一个参数
  • 甚至可能不是最后一个(&foo = bar)
  • 你以前可能有一些空间

编辑

我的第一个答案是:

 RewriteCond %{REQUEST_FILENAME} category [NC] RewriteCond %{QUERY_STRING} [^|&|%26|%20][category](=|%3D)([^&]+) [NC] RewriteRule .* /catalogsearch/result/?q=${lowercase:%2} [L,R] 

使用[^|&|%26|%20]捕捉这个事实,它可能是一个&或空格之后的起始参数或参数, %26是一个&urlencoded。

但这是错误的 ,感谢@ mootinator评论我已经检查了一点,[类别]是匹配'类别',但也'atcatcategory'和这些字母的任何组合。

 RewriteCond %{QUERY_STRING} category(=|%3D)([^&]+) [NC] 

匹配“类别”的参数,删除^允许这个参数放在任何地方。 但是这也会匹配一个名为subcategory的参数。 所以第一个字母必须是空格或&(或查询字符串的开头)。

这就是[^|&|%26|%20] ,这意味着我开始链接OR&或空间或&urlencoded。 但是那也是错误的^里面的[]意味着否定。 所以我们需要在这里使用匹配的括号: (^|&|%26|%20) ,现在它起作用了,唯一的问题是参数的值现在是%3而不是%2

然后我们赶上(类别)单词,确切地说,我们实际上应该在大写,小写和urlencoded版本的字母之后用小写和大写字母来抓住它,例如awfull [c|C|%43|%63][a|A|%61|%41][t|T|%74|...]to be continued使用括号而不是括号,地狱, 在这里检查urlencoded字符列表 。

(=|%3D)是否是urlencoded的“=”字符。 我可以使用[=|%3D]但在这种情况下, %3D不匹配,我不明白为什么(mod_rewrite是一个奇怪的事情的土地) 。 由于使用了第一个匹配的括号,我们必须使用%2变量而不是%1。

然后我们有很好的([^&]+)这意味着什么,但不是一个'&'。

在这些条件之后,我们应用RewriteRule。 我们将所有内容(这是.* )重定向到/catalogsearch/result/?q=%2我们使用%3而不是$1$3因为我们没有捕获rewriteRule上的任何内容,是最后一个条件中的第三个捕获数据,所以它是([^&]+) )。 如果您在rewriteRule中添加了QSA标志([L,R,QSA]),您甚至会在最终查询字符串上取回其他参数,以便:

 ethical?bar=toto& ethical=Foo&zorglub=titi => is redirected to catalogsearch/result/?q=foo&bar=toto&%2520ethical=Foo&zorglub=titi 

如果我玩一点网址编码:

 ethical?bar=toto%26 ethical%3DFoo&zorglub=titi => is redirected to catalogsearch/result/?q=foo&bar=toto%2526%2520ethical%253DFoo&zorglub=titi 

但是,这不是游戏的结束,我会让你处理所有的urlencoding问题,你可以用它来检测Foo值的所有变化,并将它们与tolower(在这里被打破)混合。 你甚至可能甚至没有在你的参数或额外的属性编码网址的问题,但这很有趣:-)

根据你想要做什么和具体事情需要,有两种选择。

第一个是Rob W的解决方案,它应该将用户从/category?category=News重定向到/categorysearch/result/?q=News

如果看起来您的URL区分大小写,您可能需要查看如下所示的PHP脚本:

 $matches = array(); if( preg_match( "/^/category\?category=(.+)/", $_SERVER['REQUEST_URI'], $matches ) ) { header( 'Location: http://' . $_SERVER['HTTP_HOST'] . '/categorysearch/result/?q= . strtolower($matches[1]) ); } else { //ERROR HANDLING } 

一旦解决了问题,您可以使用类似下面的规则来使用完全小写的参数进行重定向。

 RewriteRule ^category\?category=(.+)$ redirect.php [L] 

放在一起,这个解决方案会重定向/category?category=News to /categorysearch/result/?q=news

我认为

RewriteRule ^/category?category=(.*) /categorysearch/result/?q=news

会做的。