如何重写查询字符串如:
test.php?cat1[]=18&cat1[]=687&xxx[]=5&xxx[]=3&xxx[]=1&yyy[]=6
到
test.php?cat1=18,687,5&xxx=3,1&yyy=6
请注意,参数(名称和值对)是动态生成的。
答案 0 :(得分:8)
这是一个简短的PHP脚本,可以创建您想要的查询字符串。最好不要使用mod_rewrite来执行此部分,因为它只是在该范围之外:
<?php
$ret = "";
foreach($_GET as $key=>$val) {
if(is_array($val)) {
// Create the comma separated string
$value = $val[0];
$length = count($val);
for($i=1; $i < $length; $i++) {
$value .= ',' . $val[$i];
}
$ret .= "$key=$value&";
} else {
$ret .= "$key=$val&";
}
}
// Remove last '&'
$ret = substr($ret , 0, strlen($ret)-1);
// Redirect the browser
header('HTTP/1.1 302 Moved');
header("Location: /test.php?" . $ret);
?>
例如,如果将该脚本保存为/rewrite.php
,则可以在.htaccess文件中包含这些规则,以将包含数组的查询字符串的请求重新路由到/rewrite.php
:
RewriteCond %{QUERY_STRING} \[\]
RewriteRule ^test.php /rewrite.php [L,QSA]
然后,rewrite.php脚本将重写查询字符串并使用连接的查询字符串重定向浏览器。
答案 1 :(得分:3)
if (preg_match('/[\][]/',$_SERVER['QUERY_STRING'])) {
foreach ($_GET as $key => &$val) {
$_GET[$key] = is_array($val) ? implode(',', $val) : $val;
}
header('Location: test.php?'.rawurldecode(http_build_query(array_filter($_GET))));
}
答案 2 :(得分:1)
test.php的CAT1 = 18,687,5&安培; XXX = 3,1&安培; YYY = 6
尝试在代码之前插入此函数:
url_parsestring2array(& $_GET);
function url_parsestring2array($args)
{
if (empty($args) || !is_array($args) || !$args) {
return;
}
foreach ($args as $key => $val) {
$tmp = explode(',', $val);
if (count($tmp) > 1) {
$args[$key] = $tmp;
}
}
}
var_dump($_GET);
将打印
array(3){[“cat1”] =&gt; array(3){[0] =&gt; string(2)“18”[1] =&gt;串(3) “687”[2] =&gt; string(1)“5”} [“xxx”] =&gt; array(2){[0] =&gt; string(1)“3” [1] =&GT; string(1)“1”} [“yyy”] =&gt; string(1)“6”}
答案 3 :(得分:0)
我找到了一个解决方案,可以在不修改代码的情况下进行此转换。
在httpd.conf中(在我的 VirtualHost 部分中)我定义了一个重写映射:
RewriteMap programmap prg:/var/www/localhost/htdocs/chg.php
然后在.htaccess中我设置了以下规则:
RewriteEngine On
RewriteCond %{QUERY_STRING} (.*)
RewriteRule ^(script.php) $1?${programmap:%1} [L]
$ 1代表RewriteRule中的第一个“()”
%1代表RewriteCond中的第一个“()”
然后我写这个脚本“ /var/www/localhost/htdocs/chg.php ”(在PHP中,但可以是C,Perl或whatelse):
#!/usr/bin/php -f
<?php
$pos1 = 2;
$pos2 = $pos1 + 1;
$reg = '/(([a-z0-9_]+)\[\]=([^&]*))/';
while(true){
$res=array();
$buff = trim(fgets(STDIN));
if(feof(STDIN)){
break;
}
$r = preg_match_all($reg, $buff, $match,PREG_SET_ORDER);
if($r){
foreach($match as $row){
if(!isset($res[$row[$pos1]])){
$res[$row[$pos1]] = $row[$pos1]."=".$row[$pos2];
} else {
$res[$row[$pos1]] .= ",".$row[$pos2];
}
}
$out=join('&',$res);
} else {
$out=$buff;
}
echo "$out\n";
}