Parag Tyagi
Parag Tyagi

Reputation: 8970

PHP - multidimensional array to query string

Searched for so long but didn't get any feasible answer.


A) Input:

$array = array(
            'order_source' => array('google','facebook'), 
            'order_medium' => 'google-text'
          );


Which looks like:

Array
(
    [order_source] => Array
        (
            [0] => google
            [1] => facebook
        )

    [order_medium] => google-text
)


B) Required output:

order_source=google&order_source=facebook&order_medium=google-text


C) What I've tried (http://3v4l.org/b3OYo):

$arr = array('order_source' => array('google','facebook'), 'order_medium' => 'google-text');

function bqs($array, $qs='')
{
    foreach($array as $par => $val)
    {
        if(is_array($val))
        {
            bqs($val, $qs);       
        }
        else
        {
           $qs .= $par.'='.$val.'&';
        }
    }
    return $qs;
}

echo $qss = bqs($arr);


D) What I'm getting:

order_medium=google-text&


Note: It should also work for any single dimensional array like http_build_query() works.

Upvotes: 8

Views: 9158

Answers (3)

Danijel
Danijel

Reputation: 12709

I hope that this is what you are looking for, it works with single to n-dimensinal arrays.

$walk = function( $item, $key, $parent_key = '' ) use ( &$output, &$walk ) {

    is_array( $item ) 
        ? array_walk( $item, $walk, $key ) 
        : $output[] = http_build_query( array( $parent_key ?: $key => $item ) );

};

array_walk( $array, $walk );

echo implode( '&', $output );  // order_source=google&order_source=facebook&order_medium=google-text 

Upvotes: 14

rjdown
rjdown

Reputation: 9227

You don't really need to do anything special here.

$array = array(
    'order_source' => array('google', 'facebook'),
    'order_medium' => 'google-text'
);
$qss = http_build_query($array);

On the other side:

var_dump($_GET);

Result:

array(2) {
  ["order_source"]=>
  array(2) {
    [0]=>
    string(6) "google"
    [1]=>
    string(8) "facebook"
  }
  ["order_medium"]=>
  string(11) "google-text"
}

This really is the best way to send arrays as GET variables.

If you absolutely must have the output as you've defined, this will do it:

function bqs($array, $qs = false) {
    $parts = array();
    if ($qs) {
        $parts[] = $qs;
    }
    foreach ($array as $key => $value) {
        if (is_array($value)) {
            foreach ($value as $value2) {
                $parts[] = http_build_query(array($key => $value2));
            }
        } else {
            $parts[] = http_build_query(array($key => $value));
        }
    }
    return join('&', $parts);
}

Upvotes: 4

Kypros
Kypros

Reputation: 2986

Although as you found in the comments if you are trying to pass this as $_GET you will have override problems, the solution to your problem to get desired results using recursive functions would be:

function bqs($array, $qs='',$index = false)
{
    foreach($array as $par => $val)
    {
        if($index)
            $par = $index;

        if(is_array($val))
        {
            $qs = bqs($val, $qs,$par);       
        }
        else
        {
           $qs .= $par.'='.$val.'&';
        }
    }
    return $qs;
}

where i am concatinating the $qs string if it's an array and passing the index as a reference along with the value if it's an array()

fixed After supplying the $index you do not need to concatenate again. See here: http://3v4l.org/QHF5G

Upvotes: 1

Related Questions