php http_build_query 参数为null,array()忽略问题

发表于 2021-01-08  1.31k 次阅读


timg.jpg

今天在写curl的时候遇到了一个问题,在post传输数据的时候,使用了http_build_query($data)方法。

$data = [
    "userId" => 1,
    "token" => "xxxxxxxxxxx"
    "data" => null
]
curl_setopt($ch, CURLOPT_POSTFIELDS, $this->buildQuery($data));

传到后台另一个服务的时候,竟然报错了,说我少传了data~

what?data不是明明在里面吗?

通过调查,发现http_build_query在处理空参数的时候是忽略掉的,就和没传一样

//理想
userId=1&token=xxxxxxxxxxx&data=

//真实
userId=1&token=xxxxxxxxxxx

通过官方查看也没有解决方法,还有官方并不认为这是一个错误~(也对,谁让写服务的时候,这种可以为空的字段一定要传的呢~)

可木已成舟~只能想想别的方法的~

http_build_query

使用给出的关联(或下标)数组生成一个经过 URL-encode 的请求字符串。(递归变成url-encode的,有点厉害~)

解决方法:

重写一个buildQuery(),考虑到无限数组(递归解决),copy一个大佬的解决方法(稍作修改)

function buildQuery($input, $numeric_prefix = '', $arg_separator = '&', $enc_type = 2, $keyvalue_separator = '=',$prefix = '') {
        if ( is_array($input) || is_object($input)) {
            $arr = array();
            foreach ( $input as $key => $value ) {
                $name = $prefix;
                if ( strlen($prefix) ) {
                    $name .= '['.$key.']';
                } else {
                    if ( is_numeric($key) ) {
                        $name .= $numeric_prefix;
                    }
                    $name .= $key;
                }
                if ( (is_array($value) || is_object($value)) && count($value) ) {
                    $arr[] = $this->buildQuery($value,$numeric_prefix,
                        $arg_separator,$enc_type,
                        $keyvalue_separator,$name);
                } else {
                    if ($value === null || $value === "" || ((is_array($value) || is_object($value)) && count($value) == 0)) {
                        $value = "";
                    }
                    if ((is_array($value) || is_object($value)))
                    {
                        print_r($value);die;
                    }

                    if ( $enc_type === 2 ) {
                        $arr[] = rawurlencode($name) .$keyvalue_separator .rawurlencode($value);
                    } else {
                        $arr[] = urlencode($name) .$keyvalue_separator .urlencode($value);
                    }
                }
            }
            return implode($arg_separator,$arr);
        } else {
            if ( $enc_type === 2 ) {
                return rawurlencode($input);
            } else {
                return urlencode($input);
            }
        }

使用:

$data = [
    "userId" => 1,
    "token" => "xxxxxxxxxxx"
    "data" => null
]
buildQuery($data);
//userId=1&token=xxxxxxxxxxx&data=

完美~

ps:

http_build_query($array, null, '&', PHP_QUERY_RFC3986);

可以将空格转换成%20,而不是全是的+。

本站文章基于国际协议BY-NA-SA 4.0协议共享;
如未特殊说明,本站文章皆为原创文章,请规范转载。

0

一盏灯 一座城 找一人 一路的颠沛流离