我想使用http_build_query构建此url:
https://www.googleapis.com/freebase/v1/topic/m/0d6lp?filter=/common/topic/notable_for&filter=/common/topic/alias
请注意"过滤器="参数在url中出现两次,以指定两个过滤器。
我尝试这样做但遇到问题:
$service_url = 'https://www.googleapis.com/freebase/v1/topic';
$mid = '/m/0d6lp';
$params = array('filter' => '/common/topic/notable_for', 'filter' => '/common/topic/alias');
$url = $service_url . $mid . '?' . http_build_query($params);
问题在于'过滤'数组键重复两次,只有最后一个参数出现在http_build_query中。如何使用两个过滤器构建原始URL?
答案 0 :(得分:7)
这里的问题当然是PHP数组(哈希)中的每个键只能有一个值。从本质上讲,PHP哈希不是查询字符串的良好表示,因为查询字符串具有顺序,并且没有关于键的唯一性的约束。
要解决此问题,您需要一个可以处理重复键的特殊查询字符串构建器:
class QueryString {
private $parts = array();
public function add($key, $value) {
$this->parts[] = array(
'key' => $key,
'value' => $value
);
}
public function build($separator = '&', $equals = '=') {
$queryString = array();
foreach($this->parts as $part) {
$queryString[] = urlencode($part['key']) . $equals . urlencode($part['value']);
}
return implode($separator, $queryString);
}
public function __toString() {
return $this->build();
}
}
示例用法(Codepad Demo):
$qs = new QueryString();
$qs->add('filter', '1');
$qs->add('filter', '2');
var_dump($qs->build()); // filter=1&filter=2
答案 1 :(得分:0)
filter[]
因此,我建议您创建自己的函数来构建该查询。
答案 2 :(得分:0)
不是最好的解决方案,但我有一个解决方法:
$item = [
'key1' => array('value1','value2'),
'key2' => array('value3','value4')
];
$array=[
'aaa' => 'aaa',
'null' => 'null&'.preg_replace('/%5B(?:[0-9]|[1-9][0-9]+)%5D=/', '=', http_build_query($item,null,'&')),
'zzz' => 'zzz'
];
echo urldecode(http_build_query($array));
输出:
AAA AAA =&安培;空=空&安培;键1 =值&安培; KEY1 =值2&安培;键2 =值3&安培;键2 = VALUE4&安培; ZZZ = ZZZ
警告:可能这不会起作用,因为网址会是:
AAA AAA =&安培;空=空%26key1%3Dvalue1%26key1%3Dvalue2%26key2%3Dvalue3%26key2%3Dvalue4&安培; ZZZ = ZZZ
<强> 编辑: 强> 其他选项将在将结果分配给url之前预先输出结果:
preg_replace('/%5B(?:[0-9]|[1-9][0-9]+)%5D=/', '=', http_build_query($item))
输出:
键1 =值&安培; KEY1 =值2&安培;键2 =值3&安培;键2 = VALUE4
答案 3 :(得分:0)
我已经扩展了@Bailey Parker的答案来处理带有[]符号的查询字符串参数传递。此代码将创建查询字符串,其中一个键具有多个值
class QueryString
{
private $parts = array();
public function add($key, $value) {
if(empty($value))return;
if(is_array($value))
{
foreach ($value as $v)
$this->add($key,$v);
}
else
{
$this->parts[$key][] = $value;
}
}
public function build($separator = '&', $equals = '=') {
$queryString = array();
$parts = array();
foreach($this->parts as $key=>$value)
{
if(count($value) > 1)
$parts[$key] = $value;
else
$parts[$key] = $value[0];
}
$query = http_build_query($parts);
return preg_replace('/%5B(?:[0-9]|[1-9][0-9]+)%5D=/', '[]=', $query);;
}
public function __toString() {
return $this->build();
}
}
此代码还可以接受特定键的值数组
$qs = new QueryString();
$qs->add('trialId', array('1','2'));
$qs->add('packageId', '12');
$qs->add('frequencyId', '4');
var_dump($qs->build());
这个类会产生正常的查询字符串,键中有多个值加上[]符号,输出就像这样
?frequencyId=4&packageId=12&trialId[]=1&trialId[]=2