http_build_query函数的过度urlencoding [英] http_build_query function's excessive urlencoding

查看:119
本文介绍了http_build_query函数的过度urlencoding的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为什么在使用http_build_query函数构建查询字符串时,它会在方括号[]的外部值中使用urlencode编码,以及如何摆脱它?

Why when building a query string with http_build_query function, it urlencodes square brackets [] outside values and how do get rid of it?

$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[.

The function correctly urlencoded a [ in encodedBracket[ in the first line of the output but what was the reason to encode square brackets in var[foo]= and var[bar]=? As you can see, urldecoding the string also decoded reserved characters in values, encodedBracket%5B should have stayed as was for the query string to be correct and not become encodedBracket[.

根据第2.2节统一资源标识符(URI)的保留字符:通用语法

URI包括由以下内容分隔的组件和子组件: 保留"集中的字符.这些字符称为 之所以保留",是因为它们可能(也可能不会)被定义为定界符, 通用语法,每种方案特定的语法或 URI的取消引用算法的特定于实现的语法.如果 URI组件的数据将与保留字符的冲突 用作定界符,则冲突数据必须是 在URI形成之前进行百分比编码.

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.

保留= gen-delims/sub-delims

reserved = gen-delims / sub-delims

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

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

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

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

因此,http_build_query是否不应该仅在需要的地方用[] urlencoded这样的字符真正产生更具可读性的输出?我如何使它产生这样的输出?

So shouldn't http_build_query really produce more readable output with characters like [] urlencoded only where it's required? How do I make it produce such output?

推荐答案

在这里,我编写了一个快速函数来生成更好的查询字符串.它不仅不编码方括号,而且如果匹配索引,也将省略数组键. 请注意,它不支持对象或http_build_query的其他选项. $prefix参数用于递归,在初始调用时应省略.

Here's a quick function I wrote to produce nicer query strings. It not only doesn't encode square brackets but will also omit the array key if it matches the index. Note it doesn't support objects or the additional options of http_build_query. The $prefix argument is used for recursion and should be omitted for the initial call.

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);
}

这篇关于http_build_query函数的过度urlencoding的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆