apache mod_rewrite的一个规则有多种可能性

我正在build立一个相当大的网站,我的.htaccess开始感到有点臃肿,有没有一种方法来取代我现有的系统 – 每一个可能数量的可以通过的变数的一个规则,一个捕获所有expression,可以考虑不同数量的投入?

例如我目前有

RewriteRule ^([az]+)/([^/]*)/([^/]*)/([^/]*)/([^/]*)/([^/]*)$ /index.php?mode=$1&id=$2&$3=$4&$5=$6 RewriteRule ^([az]+)/([^/]*)/([^/]*)/([^/]*)$ /index.php?mode=$1&id=$2&$3=$4 RewriteRule ^([az]+)/([^/]*)$ /index.php?mode=$1&id=$2 RewriteRule ^([az]+)$ /index.php?mode=$1 

第一个反向引用总是模式 (如果存在的话),第二个反向引用总是id ,之后在input的名字和它的值之间进一步反向引用

 http://www.domain.com/search http://www.domain.com/search/3039/sort_by/name_asc/page/23 

我希望能够有一个expression式来优雅地处理所有的input。

谢谢

像Drupal一样:

  RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(.*)$ index.php?q=$1 [L,QSA] 

然后使用PHP代码来处理脚本中的所有内容

 $pathmap = (); if ($_GET["q"]){ $path = split("/", $_GET["q"]); for ($i=0; $i+1<count($path); $i++){ $pathmap[$path[$i]] = $path[$i+1]; $i++; } } 

我不知道是否可以用单个表达式来完成,但是可以用固定数量的表达式来完成,不管查询字符串多长。

你的mod_rewrite规则将被重复调用,给你什么有时称为mod_rewrite递归。 有技术可以避免它,但我想你想要使用它。

设置一个规则,用name = value替换最后一个对

继续将输入查询字符串添加到输出中。 每次通过,您的查询字符串将变得更长,您的网址将变短。

最终你只有一个匹配你的最后一个规则的值。

你必须捕捉查询字符串

 RewriteCond %{QUERY_STRING} ^(.*)$ 

然后将其添加回到%1的输出

你最终会有四行。

我知道四条线是你开始的,但是你可以根据需要匹配尽可能多的参数,而不必添加第五行。

 RewriteCond %{QUERY_STRING} ^(.*)$ RewriteRule ^(.*/)([^/]+)/([^/]+) $1?$2=$3&%1 [L] RewriteCond %{QUERY_STRING} ^(.*)$ RewriteRule ^([^/]+)/ $1.php?%1 [L] 

这将重写以下内容

 /mypage/param1/val1/param2/val2/param3/val3/... ---> /mypage.php?param1=val1&param2=val2&param3=val3&... 

只剩下一个参数时停止。 它将采用第一个“参数”,并用该名称调用.php文件。 param / val对的数量没有限制。

我不相信他们是一种方式 – 但我会说,你最好的选择是让脚本“index.php”处理一个路径,而不是做这么多的后备引用。

所以例如,你的重写就是

 RewriteBase / RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . /index.php [L] 

或者类似的…这将使$ _SERVER ['REQUEST_URI']变量包含路径信息,您可以分割和解析。

 $path = split('/', $_SERVER['REQUEST_URI']); array_shift($path); // We always have a first null value $mode = array_shift($path); 

这最终以包含模式的$ mode为结束,$ path包含一个元素数组,这是你路径的其余部分

 http://example.com/foo/bar/baz 

会留给你$ mode为'foo',$ path是一个包含'bar'和'baz'