简体   繁体   English

apache mod_rewrite适用于任何可能性的规则

[英]apache mod_rewrite one rule for any number of possibilities

I'm building a fairly large website and my .htaccess is starting to feel a bit bloated, is there a way of replacing my current system of - one rule for each of the possibile number of vars that could be passed, to one catch all expression that can account for varying numbers of inputs ? 我正在建立一个相当大的网站,我的.htaccess开始感觉有点膨胀,有没有办法取代我现有的系统 - 每个可能通过的可能数量的变量的一个规则,一个捕获所有可以解释不同数量输入的表达式?

for example I currently have: 例如,我目前有:

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

the first backreference is always the mode and (if any more exist) the second is always id , thereafter any further backreferences alternate between the name of the input and its value 第一个反向引用始终是模式,并且(如果存在的话)第二个反向引用总是id ,此后任何进一步的反向引用在输入名称和它的值之间交替

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

I would love to be able to have one expression to gracefully handle all the inputs. 我希望能够有一个表达式来优雅地处理所有输入。

Do like Drupal: 像Drupal一样:

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

And then handle all the stuff in your script using php code something like this 然后使用像这样的PHP代码处理脚本中的所有内容

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

I don't know if it can be done with a single expression, but it can be done with a fixed number of expressions, no matter how long the query string. 我不知道是否可以使用单个表达式完成,但无论查询字符串有多长,都可以使用固定数量的表达式完成。

Your mod_rewrite rules will be called repeatedly, giving you what is sometimes called mod_rewrite recursion. 您的mod_rewrite规则将被重复调用,为您提供有时称为mod_rewrite递归的内容。 There are techniques for avoiding it, but I think you want to use it. 有避免它的技术,但我认为你想使用它。

Set up a rule that replaces the last pair with name=value& 设置一个规则,用name = value&替换最后一对

Keep tacking on the input query string to the output. 继续将输入查询字符串添加到输出。 Every time through, your query string will get longer and your URL will get shorter. 每次通过,您的查询字符串将变得更长,您的URL将变得更短。

Eventually you have only a single value that matches your last rule. 最终,您只有一个与上一个规则匹配的值。

You have to capture the query string with 您必须使用捕获查询字符串

RewriteCond %{QUERY_STRING} ^(.*)$

And then you add it back to the output with %1 然后使用%1将其添加回输出

You'd end up with four lines. 你最终会得到四条线。

I know four lines is what you started with, but you'd match as many parameters as you want without having to add a fifth line. 我知道您开始使用四行,但您可以根据需要匹配任意数量的参数,而无需添加第五行。

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

This will rewrite the following 这将重写以下内容

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

It stops when there is only one parameter remaining. 当只剩下一个参数时停止。 It will take the first "parameter" and call the .php file with that name. 它将采用第一个“参数”并使用该名称调用.php文件。 There is no limit to the number of param/val pairs. param / val对的数量没有限制。

I don't believe that their is a way - but I'd say that your best bet would be to have the script "index.php" process a path instead of having to do so many back references. 我不相信他们是一种方式 - 但我会说你最好的选择是让脚本“index.php”处理一个路径,而不是必须做这么多的反向引用。

So for example, your rewriterule would be 例如,你的重写就是

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

Or similar... This would then make the $_SERVER['REQUEST_URI'] variable contain the path information, which you can split and parse. 或类似...这将使$ _SERVER ['REQUEST_URI']变量包含路径信息,您可以拆分并解析。

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

This ends up with $mode containing the mode, and $path containing an array of elements that are the rest of your path, so 这最终会得到包含模式的$ mode,以及包含路径其余部分的元素数组的$ path,所以

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

Would leave you with $mode being 'foo' and $path being an array containing 'bar' and 'baz' 会让你的$模式为'foo'而$ path是一个包含'bar'和'baz'的数组

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM