php http_build_query() 没有 url 编码
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6132721/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
http_build_query() without url encoding
提问by bgcode
Is there a way to use http_build_query()
without having it URL encode according to some RFC standard?
有没有一种方法可以http_build_query()
根据某些 RFC 标准在没有 URL 编码的情况下使用?
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 as commas in parentheses. E.g. DomainName(0) is a parameter, and the query fails if those parens are encoded.
为什么我不想对所有内容进行 URL 编码:我正在查询 Ebay API .. 他们诚实地坚持参数名称不进行 URL 编码,就括号中的逗号而言。例如 DomainName(0) 是一个参数,如果这些括号被编码,则查询失败。
回答by UserJA
You can use urldecode()
function on a result string which you get from http_build_query()
您可以urldecode()
在您获得的结果字符串上使用函数http_build_query()
回答by alex
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).
不,它似乎总是想要编码(它应该这样做,它意味着在构建 URL 的参数列表时进行 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);
键盘。
回答by Basil Musa
PHP 5.3.1 (Buggy Behavior)http_build_query DOESescape the '&' ampersand character that joins the parameters. Example: user_id=1&setting_id=2
.
PHP 5.3.1(错误行为)http_build_query确实会转义连接参数的“&”符号字符。例子:user_id=1&setting_id=2
。
PHP 5.4+http_build_query DOES NOTescape the '&' ampersand character that joins the parameters. Example: user_id=1&setting_id=2
PHP 5.4+http_build_query不会转义连接参数的“&”符号字符。例子: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:
选项#1:编写一个包装函数:
/**
* 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.
选项#2:抛弃 http_build_query 函数并编写自己的函数。
回答by Marius Bal?ytis
http_build_query() is INVALID without urlencoding. Maybe you accidentally double-encode it? For example, try to build http query for this array:
http_build_query() 在没有 urlencoding 的情况下无效。也许你不小心对它进行了双重编码?例如,尝试为这个数组构建 http 查询:
$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.
哪个是正确的。如果跳过编码,请务必避免 URL 注入攻击。
回答by onteria_
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:
您可能想尝试使用他们的 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);
?>
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.
您需要填写$appName
应用程序的名称。此外,X-EBAY-SOA-OPERATION-NAME
还需要将 设置为实际调用,如果调用不同,则修改 JSON。
回答by mhgo
You can use urldecode(). Or use http_build_query with the $arg_separatorargument.
您可以使用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 );
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'.
numeric_prefix:如果数组索引是数字,则该字符串作为前缀添加到每个索引中。在这种情况下,' test_0=bar'。
arg_separator: is used to separate arguments. If non is given php use the arg_separator.outputdifined in php.ini
arg_separator:用于分隔参数。如果非 php 使用定义在 php.ini 中的arg_separator.output
回答by david
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);
回答by Jefkine Kafunah
This could also work
这也可以工作
$fields = array(
'a' => 'A',
'b' => 'B'
);
$separator = '';
foreach($fields as $key=>$value) {
$fields_string .= $separator . $key . '=' . $value;
$separator = '&';
}
回答by Jefkine Kafunah
I tried do this recently https://gist.github.com/marcocesarato/4293986fe93139f04d8269aa3fbd47e9the difference is that this function is array recursive and compatible with PHP4. You can manage here the urlencode
我最近尝试这样做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 <[email protected]>
* @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);
}
回答by kiko carisse
I was trying to create a GET string to attach it to the end of a url like this -
我试图创建一个 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;
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 -
但是我的api不喜欢方括号中的数字,所以我找到了一个删除数字的正则表达式 -
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
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.
如果有人知道更好的正则表达式,请告诉我,我对它有点菜鸟。