我已经搜索了一些机制来在 Apache 重写中多次且非常强烈地覆盖单个查询字符串参数,但看起来没有选择这样做,即使使用最新的 Apache 版本(撰写本文时为 2.4.3) .
但是还有一个替代方案,它利用了 PHP 查询字符串解析器仅返回多个相同查询字符串参数中的最后一个这一事实。
例子:
http://www.domain.com/index.php?id=123&id=456
这将在 $_GET 中返回以下单个 (!) 条目:
array(1) {
["id"]=>
string(3) "456"
}
因此,您可以通过简单地将任何覆盖参数附加到现有查询字符串的末尾(而不在查询字符串中删除它们)来解决您的问题。重复参数的最后一次出现是使其进入 $_GET 数组的参数。
不幸的是,QSA 开关不适合这种技术,因为它总是将原始参数附加到新查询字符串的末尾。没有可以预先设置旧参数的开关。因此,您必须绕道而行,使用 RewriteCond 自己捕获并添加原始查询字符串,而不是使用 QSA:
RewriteCond %{QUERY_STRING} ^(.*)$
RewriteRule ^([A-Za-z0-9\_]+)$ index.php?%1&rewrite=$1 [L]
RewriteCond 的唯一功能是捕获 %1 中的查询字符串。条件的正则表达式(.*)
总是匹配的,所以下面的 RewriteRule 总是被执行。
使用这种技术,您的上述测试用例将重写为...
http://www.domain.com/index.php?rewrite=some_value&rewrite=this_rewrite_will_match_the_above_rule
...这将由 PHP 查询字符串解析器解释为
$_GET["id"] => "this_rewrite_will_match_the_above_rule"
...这就是你想要的。
请注意,这仅在您从 PHP 的 $_GET 数组中获取查询字符串值时才有效。$_SERVER["QUERY_STRING"]
如果您解析自己的内容或使用任何其他编程语言,它不一定会起作用。