http_build_query() without url encoding
Is there a way to use http_build_query() without having it URL encode according to some RFC standard?
Why I don't want to URL encode everything: I'm querying the Ebay API.. They honestly insist on parameter names not being URL encoded, as far 开发者_如何学Pythonas commas in parentheses. E.g. DomainName(0) is a parameter, and the query fails if those parens are encoded.
You can use urldecode() function on a result string which you get from http_build_query()
PHP 5.3.1 (Buggy Behavior)
http_build_query DOES escape the '&' ampersand character that joins the parameters. Example: user_id=1&setting_id=2.
PHP 5.4+
http_build_query DOES NOT escape the '&' ampersand character that joins the parameters. Example: user_id=1&setting_id=2
Example:
$params = array(
    'user_id' => '1', 
    'setting_id' => '2'
);
echo http_build_query($params);
// Output for PHP 5.3.1:
user_id=1&setting_id=2   // NOTICE THAT: '&' character is escaped
// Output for PHP 5.4.0+:
user_id=1&setting_id=2       // NOTICE THAT: '&' character is NOT escaped
Solution when targeting multiple version
Option #1: Write a wrapper function:
/** 
 * This will work consistently and will never escape the '&' character
 */
function buildQuery($params) {
    return http_build_query($params, '', '&');
}
Option #2: Ditch the http_build_query function and write your own.
Nope, it appears to always want to encode (which it should, it is meant to URL encode when building a list of params for a URL).
You could make your own...
$params = array('a' => 'A', 'b' => 'B');
$paramsJoined = array();
foreach($params as $param => $value) {
   $paramsJoined[] = "$param=$value";
}
$query = implode('&', $paramsJoined);
CodePad.
You might want to try their JSON API instead. I tried to get a working sample, but I don't have an app name so I can't verify the result. Here's the code:
<?php
$appName = "Your App Name Here";
$post_data = array(
  'jsonns.xsi' => 'http://www.w3.org/2001/XMLSchema-instance',
  'jsonns.xs' => 'http://www.w3.org/2001/XMLSchema',
  'jsonns.tns' => 'http://www.ebay.com/marketplace/search/v1/services',
  'tns.findItemsByKeywordsRequest' => array(
    'keywords' => 'harry potter pheonix'
  )
);
$headers = array(
  "X-EBAY-SOA-REQUEST-DATA-FORMAT: JSON", 
  "X-EBAY-SOA-RESPONSE-DATA-FORMAT: JSON",
  "X-EBAY-SOA-OPERATION-NAME: findItemsByKeywords",
  "X-EBAY-SOA-SECURITY-APPNAME: $appName"
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'http://svcs.ebay.com/services/search/FindingService/v1');
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($post_data));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$result = curl_exec($ch);
if($result) {
  $response = json_decode($result);
}
curl_close($ch);
?>
You'll need to to fill $appName with whatever the name of the app is. Also the X-EBAY-SOA-OPERATION-NAME will need to be set to the actual call, and the JSON modified if the call is different.
http_build_query() is INVALID without urlencoding. Maybe you accidentally double-encode it? For example, try to build http query for this array:
$params = array('a' => 'a&b=b');
Without encoding, you would get
a=a&b=b
When properly encoded, you would get
a=a%26b%3Db
which is correct. If you skip encoding, be sure to avoid URL injection attacks.
You can use urldecode(). Or use http_build_query with the $arg_separator argument.
    $query_data= $data = array('bar', 'baz'=>'boom');
    $numeric_prefix= 'test_';
    $arg_separator = '&';
    $http_query = http_build_query ( $query_data, $numeric_prefix, $arg_separator );
    var_dump( $http_query );
the output of the above is
     string 'test_0=bar&baz=boom' (length=19)
numeric_prefix: if the array indexes are numbers, this string is added as prefix in each index. In this case the 'test_0=bar'.
arg_separator : is used to separate arguments. If non is given php use the arg_separator.output difined in php.ini
See php http_build_query
I was trying to create a GET string to attach it to the end of a url like this -
$get_params = array(
    'include' => array(
        'enrollments',
        'current_grading_period_scores'
    ),
    'enrollment_type' => array(
        'student',
    ),
);
$get_params = http_build_query($get_params);
$get_params = urldecode($get_params);
$url = $domain.$slug;
$url = $url.'?'.$get_params;
echo $url;
which prints out
include[0]=enrollments&include[1]=current_grading_period_scores&enrollment_type[0]=student
But my api didn't like the numbers in the square brackets, so I found a regular expression that removes the numbers -
preg_replace('/[[0-9]+]/', '[]', $get_params);
The final code, and the result -
$get_params = array(
    'include' => array(
        'enrollments',
        'current_grading_period_scores'
    ),
    'enrollment_type' => array(
        'student',
    ),
);
$get_params = http_build_query($get_params);
$get_params = urldecode($get_params);
$get_params = preg_replace('/[[0-9]+]/', '[]', $get_params);
$url = $domain.$slug;
$url = $url.'?'.$get_params;
echo $url;
Prints out -
include[]=enrollments&include[]=current_grading_period_scores&enrollment_type[]=student
If someone knows of a better regex let me know, I'm kind of a noob with it.
my take on alex's answer but is faster
$params = array('a' => 'A', 'b' => 'B');
$query = '';
foreach ($params as $param => $value) {
   $query .= $param.'='.$value .'&';
}
echo substr($query, 0, -1);
This could also work
$fields = array(
    'a' => 'A', 
    'b' => 'B'
 );
$separator = '';
foreach($fields as $key=>$value) {
    $fields_string .= $separator . $key . '=' . $value; 
    $separator = '&'; 
}
I tried do this recently https://gist.github.com/marcocesarato/4293986fe93139f04d8269aa3fbd47e9 the difference is that this function is array recursive and compatible with PHP4. You can manage here the urlencode
<?php
/**
 * Build URL query params
 * as http_build_query build a query url the difference is 
 * that this function is array recursive and compatible with PHP4
 *
 * @author Marco Cesarato <cesarato.developer@gmail.com>
 * @param $query
 * @param string $parent
 * @return string
 *
 * @example
 * $p = array('abbreviations' => array('google' => 'ggle', 'facebook' => array('abb_key' => 'fbook', 'fcbk')), 'key' => 'value');
 * echo url_build_query($p);
 */
function url_build_query($query, $parent = null){
    $query_array = array();
    foreach($query as $key => $value){
        $_key = empty($parent) ?  urlencode($key) : $parent . '[' . urlencode($key) . ']';
        if(is_array($value)) {
            $query_array[] = url_build_query($value, $_key);
        } else {
            $query_array[] = $_key . '=' . urlencode($value);
        }
    }
    return implode('&', $query_array);
}
 
         加载中,请稍侯......
 加载中,请稍侯......
      
精彩评论