8

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.

6
  • Sorry, but this makes absolutely no sense: order_source=google&order_source=facebook You're overwriting the order_source GET variable with the second, so you'll not get the first? What would work is: order_source[]=google&order_source[]=facebook Commented Oct 25, 2014 at 15:24
  • Not sure what you are going to use it for, but because you mention http_build_query a note: order_source=google&order_source=facebook is not going to work Commented Oct 25, 2014 at 15:24
  • I'll explain. It's an Order Management System where the user clicks on multiple links and it acts like Filters in Excel sheets. Somethings like that. Commented Oct 25, 2014 at 15:27
  • @JaredFarrish: Yes. I know its gonna overwrite hence I've already written a function which takes whole of the query string as input and gives a multidimensional array as output. Commented Oct 25, 2014 at 15:29
  • Why? PHP understands the order_status[]=google syntax as array already. Another, probably much simpler option would be to JSON encode your array and pass it as a variable, then json_decode() it back to it's array on the server. Commented Oct 25, 2014 at 15:32

3 Answers 3

14

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 
Sign up to request clarification or add additional context in comments.

Comments

4

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

1 Comment

if you want to send http_build_query result via post then urldecode() the output before doing so; for GET requests its all fine
1

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

2 Comments

Check the fix without concatenation when it's an array
it's not safe to simply do key=value, either part may need encoding. That's what http_build_query is for

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.