2010-12-14 79 views
4

怎麼可能到查詢字符串改寫等:阿帕奇重寫查詢字符串(複選框陣列)

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 

注意,參數(名稱和值對)是動態生成的。

+1

這是絕對可能的。但我不會用mod_rewrite而是用PHP。 – Gumbo 2010-12-14 08:00:54

+0

我也有這個問題...... – 2011-11-21 19:16:44

回答

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腳本將改寫查詢字符串和重定向與串聯查詢字符串的瀏覽器。

+0

在我的上下文中,我使用的是WordPress,而您的示例中的「test.php」是一個名爲「advanced-search」的頁面(這是一個已被重寫的漂亮的永久鏈接。 htaccess)位於@「http:// root/wordpress/advanced-search /」;查詢顯示爲:「http:// root/wordpress/advanced-search/...;是否需要對腳本進行任何調整以使其正常工作?謝謝! – 2011-11-21 22:36:31

+0

查詢是什麼樣子的?在/ advanced-search /之後沒有任何東西,你可能想要改寫爲/ wordpress/advanced-search/to /rewrite.php(或者你想命名的任何東西),然後在rewrite.php的底部,使用'pring(get_file_contents(「http:// your-host/wordpress/advanced-search?$ ret」));'而不是用'header()' – 2011-11-21 22:45:28

+0

重定向瀏覽器,查詢如下所示:10.0.1.4:8888 [斜線] wordpress [斜槓]高級搜索[斜線]?property_type [] =閣樓&property_type [] =住宅 – 2011-11-21 23:00:25

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」] => array(3){[0] => string(2)「18」[1] => string(3) 「687」[2] => 1)「5」} [「xxx」] => array(2){[0] => string(1)「3」 [1] =>串(1) 「1」} [ 「YYY」] =>串(1) 「6」}

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)))); 
} 
+0

考慮''/ [\] [] /'',如果你改變它,只分配給'$ _GET [$ key]';你甚至可以用'foreach($ _GET as $ key =>&$ val)'直接賦值給'$ val',這樣數組就不會被複制。否則,做得好(+1)。 – PointedEars 2011-11-28 17:16:06

+0

@PointedEars:好點,TNX ;-)我也添加了一些東西去掉空val以防萬一。 ;-) – 2011-11-29 00:34:57

0

我找到了一個解決方案來做這個轉換而不用修改代碼。

在httpd.conf(在我虛擬主機部分)我定義了一個重寫地圖:

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"; 
}