views:

47

answers:

4

While doing some query string processing I stumbled upon this:

<?php
$in='a=6&b=7&8=c';
parse_str($in,$qs);
$out=array_merge($qs,array('9'=>'d'));
print_r($out);
?>

We get:

Array
(
    [a] => 6
    [b] => 7
    [0] => c
    [1] => d
)

Instead of:

Array
(
    [a] => 6
    [b] => 7
    [8] => c
    [9] => d
)

I understand why this is happening ('8' and '9' are being treated as numeric keys) but I'm not happy that I have to do this the long way round.

There must be a way to keep it simple. How do you slice, dice and cook your query strings?

+1  A: 

I am using http_build_query() function.
And NEVER use numeric keys for the query string/any request variables.

Col. Shrapnel
http_build_query() comes later in the pipeline. Good advice on not using numeric keys in query strings but my module needs to pass very strict tests which includes things that would make even you cry ;)
zaf
@zaf I won't cry, but PHP would.
Col. Shrapnel
+1  A: 

The issue is that array_merge renumbers numeric keys so that they start from zero (if you var_dump your $qs array before the merge, you will see that there is a key named 8). Either don't use numeric keys, or just push straight onto the array instead of using array_merge:

$in = 'a=6&b=7&8=c';
parse_str($in,$qs);
$out = $qs;
$out[9] = 'd';

Note that parse_str also has the side effect of setting variables in the local scope, so after you parse your query string, $a will be 6 and $b will be 7. This may or may not be desired.

Daniel Vandersluis
Giving the extra parameter to parse_str does not have the side effect (thats what the manual says) of creating a local variable. As for pushing onto the array, I'll need it a bit more dynamic :)
zaf
@zaf You're right, I must have missed that.
Daniel Vandersluis
And @Mark Baker's method of unioning an array would work nicely but I wanted to give a different option instead of duplicating ;)
Daniel Vandersluis
+2  A: 

Consider using the UNION operator for arrays

$out=$qs+array('9'=>'d');
print_r($out);
Mark Baker
New to me! I'll check it out. The only thing is that if a key already exists then it needs to be overwritten with the new value. I'll test.
zaf
Oo! Nearly! If the array on the right contains a key that is in the left array then it gets ignored. Ack!
zaf
Try reversing the order if necessary: $out=array('9'=>'d')+$qs; depending on which value you want when the union encounters matching keys
Mark Baker
+1  A: 

Why dont you just do a simple loop over one array and checking of key exists or not?

If it exists then update the value otherwise add a new array element. Thats waht I do to avoid problems like these.

Yehonatan
Probably the safest bet!
zaf