有没有一种方法可以用http_build_query使用同名参数自动构建查询?如果我做一些
http_build_query
array('foo' => 'x', 'foo' => 'y');
它们显然在数组中被覆盖,但即使我这样做:
array('foo' => array('x', 'y'));
该函数创建了类似foo[0]=x&foo[1]的东西,这不是我想要的,因为我需要这种格式的参数foo=x&foo=y。
foo[0]=x&foo[1]
foo=x&foo=y
pengsaosao1#
您可以通过对http_build_query()的结果进行替换来解决这个问题,其中[0],[1],.,后缀是URL编码的。
http_build_query()
[0]
[1]
$vars = array('foo' => array('x', 'y')); $query = http_build_query($vars); # foo%5B0%5D=x&foo%5B1%5D=y (URL-encoded foo[0]=x&foo[1]=y) $query = preg_replace('/%5B\d+%5D(?==)/', '', $query); # foo=x&foo=y
look-ahead((?= … ))确保它只替换名称末尾的值,因为它们后面总是跟着=。PHP不会生成前导零的索引,所以\d+(1位或更多位)足以检测它们。有些系统要求方括号内没有索引。在这种情况下,您可以使用以下命令:
(?= … )
=
\d+
$query = preg_replace('/(?<=%5B)\d+(?=%5D=)/', '', $query); # foo%5B%5D=x&foo%5B%5D=y (URL-encoded foo[]=x&foo[]=y)
jogvjijk2#
下面是我创建的一个函数,用于构建查询并保留名称。我创建这个是为了与第三方API一起使用,该API需要具有相同名称的多个查询字符串参数。
function custom_build_query( array|object $query_data, string $numeric_prefix = "", ?string $arg_separator = null, int $encoding_type = PHP_QUERY_RFC1738 ): string { // Cast to array if object is supplied. $query_data = is_object($query_data) ? get_object_vars($query_data) : $query_data; // Use supplied arg_separator value, defaulting to the `arg_separator.output` php configuration. $arg_separator = $arg_separator ?? ini_get("arg_separator.output"); // If PHP_QUERY_RFC3986 is specified, use rawurlencode to encode parameters. $encoding_function = $encoding_type === PHP_QUERY_RFC3986 ? "rawurlencode" : "urlencode"; $query = []; foreach ($query_data as $name => $value) { $value = (array) $value; $name = is_int($name) ? $numeric_prefix . $name : $name; array_walk_recursive($value, function ($value) use (&$query, $name, $encoding_function) { $query[] = $encoding_function($name) . "=" . $encoding_function($value); }); } return implode($arg_separator, $query); }
使用方法:
echo custom_build_query(['a' => 1, 'b' => 2, 'c' => [3, 4]]);
输出量:
a=1&b=2&c=3&c=4
注意:该函数的签名与http_build_query完全兼容。当然,唯一的区别是,该函数将不使用括号作为子数组参数。
2条答案
按热度按时间pengsaosao1#
您可以通过对
http_build_query()
的结果进行替换来解决这个问题,其中[0]
,[1]
,.,后缀是URL编码的。look-ahead(
(?= … )
)确保它只替换名称末尾的值,因为它们后面总是跟着=
。PHP不会生成前导零的索引,所以\d+
(1位或更多位)足以检测它们。有些系统要求方括号内没有索引。在这种情况下,您可以使用以下命令:
jogvjijk2#
下面是我创建的一个函数,用于构建查询并保留名称。我创建这个是为了与第三方API一起使用,该API需要具有相同名称的多个查询字符串参数。
使用方法:
输出量:
注意:该函数的签名与
http_build_query
完全兼容。当然,唯一的区别是,该函数将不使用括号作为子数组参数。