Skip to content

Instantly share code, notes, and snippets.

@olimortimer
Created February 4, 2014 10:20
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save olimortimer/8801155 to your computer and use it in GitHub Desktop.
Save olimortimer/8801155 to your computer and use it in GitHub Desktop.
PHP: Replacement http_build_query
<?php
/**
* Recursive function to work through the data
*
* http_build_query in php 5 will screw up array serialisation by encoding the square brackets
* and make it incompatible for passing to an URL's GET segment or sending through post data manually
*
* Thanks to Marco K. (link below), A version intended for php < 5 actually encodes the data correctly
*
* @see http://uk.php.net/manual/en/function.http-build-query.php#90438
* @param array|object $data
* @param string $prefix
* @param string $sep
* @param string $key
* @return string
*/
function query_string_encode($data, $prefix = '', $sep = '&', $key = '') {
$ret = array();
//if it's not an array or object, then it's not iterable (has no keys) so just return it
if (!is_array($data) && !is_object($data))
return rawurlencode($data);
foreach ($data as $k => $v) {
//cleanup and prepend prefix to the current key
if ($prefix != null) {
$k = rawurlencode($prefix . $k);
}
//if the key is not empty, it implies it's been called recursively so set up the query string array key
if ((!empty($key)) || ($key === 0))
$k = $key . '[' . rawurlencode($k) . ']';
//now we work on the value
if (is_array($v)) {
//just recusively call this function, eventually we'll get all the multidimensional array elements
//unless some idiot does recursive references, at which point the loop will be infinite
array_push($ret, query_string_encode($v, '', $sep, $k));
} elseif (is_object($v)) {
//handle objects differently. First see if it has the toQueryString method
if (method_exists($v, 'toQueryString')) {
$refl = new ReflectionMethod($v, 'toQueryString');
//the method is valid, so run it
if ($refl->isPublic() && !$refl->isStatic()) {
$obj_str = $v->toQueryString('', $sep, $k);
} else {
//it's not valid so we need to iterate the object
$obj_str = $v;
}
} else {
//the method doesn't exist so we need to iterate through it
$obj_str = $v;
}
//it seems it has returned an array or the method wasn't found, so let's iterate through it
if (is_array($obj_str) || is_object($obj_str)) {
array_push($ret, $this->_encode($obj_str, '', $sep, $k));
} else {
//we had a return value that wasn't an array
//as the return is from toQueryString which calls this class (everything else is considered an array), we will trust it
array_push($ret, $k . '=' . $obj_str);
}
} else {
array_push($ret, $k . '=' . rawurlencode($v));
}
}
//set the seperator and implode to create the final string
if (empty($sep))
$sep = ini_get('arg_separator.output');
return implode($sep, $ret);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment