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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.