array("fo-6ren">
gpt4 book ai didi

php - http_build_query 函数的 urlencoding 过多

转载 作者:搜寻专家 更新时间:2023-10-31 22:04:42 29 4
gpt4 key购买 nike

为什么在使用 http_build_query 函数构建查询字符串时,它会将方括号 [] urlencode 到值之外,如何摆脱它?

$query = array("var" => array("foo" => "value", "bar" => "encodedBracket["));
$queryString = http_build_query($query, "", "&");
var_dump($queryString);
var_dump("urldecoded: " . urldecode($queryString));

输出:

var%5Bfoo%5D=value&var%5Bbar%5D=encodedBracket%5B
urldecoded: var[foo]=value&var[bar]=encodedBracket[

该函数在输出第一行的 encodedBracket[ 中正确地对 [ 进行了 urlencode,但是在 var[foo] 中对方括号进行编码的原因是什么=var[bar]=?如您所见,对字符串进行 urldecoding 还对值中的保留字符进行解码,encodedBracket%5B 应该保持原样以使查询字符串正确,而不是变成 encodedBracket[

根据 section 2.2 Reserved Characters of Uniform Resource Identifier (URI): Generic Syntax

URIs include components and subcomponents that are delimited by characters in the "reserved" set. These characters are called "reserved" because they may (or may not) be defined as delimiters by the generic syntax, by each scheme-specific syntax, or by the implementation-specific syntax of a URI's dereferencing algorithm. If data for a URI component would conflict with a reserved character's purpose as a delimiter, then the conflicting data must be percent-encoded before the URI is formed.

reserved = gen-delims / sub-delims

gen-delims = ":" / "/" / "?" / "#" / "[" / "]" / "@"

sub-delims = "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / ";" / "="

那么 http_build_query 真的不应该产生更具可读性的输出吗?像 [] 这样的字符只在需要的地方进行 urlencode 编码?我如何让它产生这样的输出?

最佳答案

这是我编写的一个快速函数,用于生成更好的查询字符串。它不仅不对方括号进行编码,而且如果与索引匹配,还会省略数组键。请注意,它不支持对象或 http_build_query 的附加选项。 $prefix 参数用于递归,在初始调用时应省略。

function http_clean_query(array $query_data, string $prefix=null): string {
$parts = [];
$i = 0;
foreach ($query_data as $key=>$value) {
if ($prefix === null) {
$key = rawurlencode($key);
} else if ($key === $i) {
$key = $prefix.'[]';
$i++;
} else {
$key = $prefix.'['.rawurlencode($key).']';
}
if (is_array($value)) {
if (!empty($value)) $parts[] = http_clean_query($value, $key);
} else {
$parts[] = $key.'='.rawurlencode($value);
}
}
return implode('&', $parts);
}

关于php - http_build_query 函数的 urlencoding 过多,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21046623/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com