没有URL编码的http_build_query()

| 有没有一种方法可以使用
http_build_query()
而不按照某些RFC标准对URL进行编码? 为什么我不想对所有内容进行URL编码:我正在查询Ebay API。.老实说,就括号中的逗号而言,他们坚持不对参数名称进行URL编码。例如。 DomainName(0)是一个参数,如果对这些括号进行了编码,查询将失败。     
已邀请:
您可以在从
http_build_query()
得到的结果字符串上使用
urldecode()
函数     
不,它似乎总是想编码(在为URL构建参数列表时应该对URL进行编码)。 你可以自己做...
$params = array(\'a\' => \'A\', \'b\' => \'B\');

$paramsJoined = array();

foreach($params as $param => $value) {
   $paramsJoined[] = \"$param=$value\";
}

$query = implode(\'&\', $paramsJoined);
键盘。     
PHP 5.3.1(Buggy行为) http_build_query不会转义连接参数的\'&\'和号。例如:
user_id=1&setting_id=2
。 PHP 5.4以上 http_build_query不会转义连接参数的\'&\'和号。示例:
user_id=1&setting_id=2
例:
$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
定位多个版本时的解决方案 选项#1:编写包装函数:
/** 
 * This will work consistently and will never escape the \'&\' character
 */
function buildQuery($params) {
    return http_build_query($params, \'\', \'&\');
}
选项2:放弃http_build_query函数并编写自己的函数。     
您可能想尝试使用他们的JSON API。我尝试获取一个有效的示例,但是我没有应用名称,因此无法验证结果。这是代码:
<?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);
?>
无论应用名称是什么,您都需要填写ѭ9。此外,还需要将“ 10”设置为实际调用,如果调用不同,则修改JSON。     
没有进行urlencoding的http_build_query()是无效的。也许您不小心对它进行了双重编码? 例如,尝试为该数组构建http查询:
$params = array(\'a\' => \'a&b=b\');
没有编码,您将得到
a=a&b=b
正确编码后,您将获得
a=a%26b%3Db
哪个是对的。如果您跳过编码,请确保避免URL注入攻击。     
您可以使用urldecode()。 或将http_build_query与$ arg_separator参数一起使用。
    $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 );
上面的输出是
     string \'test_0=bar&baz=boom\' (length=19)
numeric_prefix:如果数组索引是数字,则此字符串将作为前缀添加到每个索引中。在这种情况下,\'test_0 = bar \'。 arg_separator:用于分隔参数。如果未指定php,请使用php.ini中定义的arg_separator.output 参见php http_build_query     
我对alex的回答,但速度更快
$params = array(\'a\' => \'A\', \'b\' => \'B\');
$query = \'\';

foreach ($params as $param => $value) {
   $query .= $param.\'=\'.$value .\'&\';
}

echo substr($query, 0, -1);
    
这也可以工作
$fields = array(
    \'a\' => \'A\', 
    \'b\' => \'B\'
 );

$separator = \'\';
foreach($fields as $key=>$value) {
    $fields_string .= $separator . $key . \'=\' . $value; 
    $separator = \'&\'; 
}
    
我最近尝试这样做https://gist.github.com/marcocesarato/4293986fe93139f04d8269aa3fbd47e9,不同之处在于此函数是数组递归的并且与PHP4兼容。您可以在此处管理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);
}
    
我试图创建一个GET字符串,将其附加到这样的url的末尾-
$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;
打印出来
include[0]=enrollments&include[1]=current_grading_period_scores&enrollment_type[0]=student
但是我的api不喜欢方括号中的数字,因此我找到了删除数字的正则表达式-
preg_replace(\'/[[0-9]+]/\', \'[]\', $get_params);
最终代码和结果-
$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;
打印输出-
include[]=enrollments&include[]=current_grading_period_scores&enrollment_type[]=student
如果有人知道更好的正则表达式,请告诉我,我有点菜鸟了。     

要回复问题请先登录注册