I ran into a problem today where I was passing a key with the value set to an empty array to http_build_query()
. E.g.:
$args = array(\"foo\", \"bar\
I've reimplemented http_build_query to leave empty objects/arrays in the returned query string (suffixed by an '=' symbol). I've enhanced it a bit from the default functionality as well, so all-in-all:
I have not tested this in a production environment (no idea about performance or bugs), and it is not optimized, but very well spelled out.
function buildQuery($input,$numeric_prefix='',
$arg_separator='&',$enc_type=2,
$keyvalue_separator='=',$prefix='') {
if ( is_array($input) ) {
$arr = array();
foreach ( $input as $key => $value ) {
$name = $prefix;
if ( strlen($prefix) ) {
$name .= '[';
if ( !is_numeric($key) ) {
$name .= $key;
}
$name .= ']';
} else {
if ( is_numeric($key) ) {
$name .= $numeric_prefix;
}
$name .= $key;
}
if ( (is_array($value) || is_object($value)) && count($value) ) {
$arr[] = buildQuery($value,$numeric_prefix,
$arg_separator,$enc_type,
$keyvalue_separator,$name);
} else {
if ( $enc_type === 2 ) {
$arr[] = rawurlencode($name)
.$keyvalue_separator
.rawurlencode($value?:'');
} else {
$arr[] = urlencode($name)
.$keyvalue_separator
.urlencode($value?:'');
}
}
}
return implode($arg_separator,$arr);
} else {
if ( $enc_type === 2 ) {
return rawurlencode($input);
} else {
return urlencode($input);
}
}
}
Example:
$arr = array(
'hello' => 'world',
'colors' => array('red','green','blue'),
'emptyArr' => array(),
'nested' => array(
'empty' => array(),
'fruits' => array('orange','banana','apple'),
'curly' => 'sue',
'assoc' => array('a'=>'alpha','b'=>'bravo','c'=>'charlie')
)
);
echo buildQuery($arr);
Outputs: hello=world&colors%5B%5D=red&colors%5B%5D=green&colors%5B%5D=blue&emptyArr=&nested%5Bempty%5D=&nested%5Bfruits%5D%5B%5D=orange&nested%5Bfruits%5D%5B%5D=banana&nested%5Bfruits%5D%5B%5D=apple&nested%5Bcurly%5D=sue&nested%5Bassoc%5D%5Ba%5D=alpha&nested%5Bassoc%5D%5Bb%5D=bravo&nested%5Bassoc%5D%5Bc%5D=charlie
I hope this finds someone well.