2010-12-14 51 views
4

Comment est-il possible de réécrire la chaîne de requête comme:Apache réécriture chaîne de requête (réseau de case à cocher)

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 

Notez que les paramètres (paires nom-valeur) sont générés dynamiquement .

+1

Il est tout à fait possible.Mais je ne le ferais pas avec mod_rewrite mais avec PHP. – Gumbo

+0

J'ai aussi cette question ... –

Répondre

8

Voici un court script PHP qui crée la chaîne de requête que vous voulez. Il est préférable de ne pas faire partie en utilisant mod_rewrite, parce qu'il est tout simplement en dehors de ce champ:

<?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); 

?> 

Si vous enregistrez ce script comme /rewrite.php, par exemple, vous pouvez inclure ces règles dans le fichier .htaccess pour rediriger les demandes avec des chaînes de requête contenant des tableaux à /rewrite.php:

RewriteCond %{QUERY_STRING} \[\] 
RewriteRule ^test.php /rewrite.php [L,QSA] 

Ensuite, le script rewrite.php réécrit la chaîne de requête et rediriger le navigateur avec la chaîne de requête concaténer.

+0

Dans mon contexte j'utilise WordPress, et le "test.php" dans votre exemple est une page nommée "advanced-search" (qui est un joli permalien déjà réécrit par. htaccess) situé @ "http: // root/wordpress/advanced-search /"; les requêtes apparaissent comme suit: "http: // root/wordpress/advanced-search/...; Y at-il des ajustements que je dois faire à votre script pour le faire fonctionner? Merci! –

+0

A quoi ressemblent les requêtes? Vous avez probablement besoin de changer la réécriture en/wordpress/advanced-search/en /rewrite.php (ou ce que vous voulez nommer), puis en bas de rewrite.php, utilisez 'pring (get_file_contents (" http: // votre-hôte/wordpress/advanced-search? $ ret "));' au lieu de rediriger le navigateur avec 'header()' –

+0

les requêtes ressemblent à: 10.0.1.4:8888 [barre oblique] wordpress [barre oblique] advanced-search [barre oblique]? property_type [] = loft & property_type [] = résidentiel –

1

test.php cat1 = xxx 18,687,5 & = yyy = & 3,1 6

essayer d'insérer cette fonction avant votre code:

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); 

imprimera

array (3) {["cat1"] => array (3) {[0] => chaîne (2) "18" [1] => chaîne (3) "687" [2] => chaîne (1) "5"} ["xxx"] => array (2) {[0] => string (1) "3" [1] => Chaîne (1) "1"} [ "yyy"] => string (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

Considérons ''/[\] []/''et n'attribuant que' $ _GET [$ key] 'si vous le changez; vous pourriez même avoir 'foreach ($ _GET comme $ key => & $ val)' et assigner directement '$ val', donc le tableau n'est pas copié. Sinon, bien fait (+1). – PointedEars

+0

@PointedEars: des points sympas, tnx ;-) J'ai aussi ajouté quelque chose pour enlever le val vide juste au cas où. ;-) –

0

I trouvé une solution pour faire cette transformation sans modifier le code.

Dans le httpd.conf (dans mon VirtualHost section) Je définir une feuille de réécriture:

RewriteMap programmap prg:/var/www/localhost/htdocs/chg.php 

Ensuite, dans le .htaccess je mis les règles suivantes:

RewriteEngine On 

RewriteCond %{QUERY_STRING} (.*) 
RewriteRule ^(script.php) $1?${programmap:%1} [L] 

1 $ support pour le premier "()" dans RewriteRule

% 1 représente le premier "()" dans RewriteCond

Alors j'écrire ce script "/var/www/localhost/htdocs/chg.php" (en PHP, mais peut être en C, Perl, ou 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"; 
}