Apache rewrite query string (checkbox array)

How is it possible to rewrite the query string like:

test.php?cat1[]=18&cat1[]=687&xxx[]=5&xxx[]=3&xxx[]=1&yyy[]=6

to

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

Note that the parameters (name and value pairs) are generated dynamically.

Related posts

Leave a Reply

4 comments

  1. Here’s a short php script that creates the query string that you want. It’s best not to do this part using mod_rewrite, because it’s simply outside of that scope:

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

    If you save that script as /rewrite.php, for example, then you can include these rules in the .htaccess file to reroute requests with query strings containing arrays to /rewrite.php:

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

    Then the rewrite.php script will rewrite the query string and redirect the browser with the concatenated query string.

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

    try to insert this function before your 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);
    

    will print

    array(3) { [“cat1”]=> array(3) { [0]=> string(2) “18” [1]=> string(3)
    “687” [2]=> string(1) “5” } [“xxx”]=> array(2) { [0]=> string(1) “3”
    [1]=> string(1) “1” } [“yyy”]=> string(1) “6” }

  3. I found a solution to do this transformation without modifying the code.

    In the httpd.conf (in my VirtualHost section) I define a rewrite map:

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

    Then in the .htaccess I set the following rules:

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

    $1 stand for first “()” in RewriteRule

    %1 stand for first “()” in RewriteCond

    Then I write this script “/var/www/localhost/htdocs/chg.php” (in PHP but can be in C, Perl, or 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 "$outn";
    }