PHP cURL请求中CURLOPT_POSTFIELDS只支持一维数组

使用PHP发起请求时,咱们会经常使用cURL方法,具体的PHP请求方式能够参考 PHP cURL请求详解 这篇文章。php

cURL发起POST请求

在使用中,若是你须要发送POST的请求,须要配置CURLOPT_POSTCURLOPT_POSTFIELDS两个参数,curl请求封装后的源码以下:json

/**
 * 使用cURL方法获取接口数据
 * @param $uri 请求的url
 * @param $param 发起POST请求时携带的参数
 * @return array 请求返回的数据,解析成json格式
 */
public function fetchApi($uri, $param = array()) {
    // 初始化curl
    $ch = curl_init($uri);
    curl_setopt_array($ch, array(
        // 不直接输出,返回到变量
        CURLOPT_RETURNTRANSFER => true,
        // 设置超时为60s,防止机器被大量超时请求卡死
        CURLOPT_TIMEOUT => 60
    ));
    // 支持POST请求
    if (!empty($param)) {
        curl_setopt_array($ch, array(
            CURLOPT_POST => true,
            // 设置POST参数
            CURLOPT_POSTFIELDS => http_build_query($param)
        ));
    }
    // 请求数据
    $data = curl_exec($ch);
    // 关闭请求
    curl_close($ch);
    // 对数据进行编码,方便先后端数据处理
    return json_decode($data);
}

POST参数

若是须要使用POST方法,你须要设置CURLOPT_POST参数为true,并在CURLOPT_POSTFIELDS中传递post参数。segmentfault

为何使用http_build_query

须要注意的是CURLOPT_POSTFIELDS参数只支持一维数组参数,不然会出错,你能够本地测试:后端

为了测试这个功能,咱们须要将上面的代码作一处修改:
替换行 CURLOPT_POSTFIELDS => http_build_query($param)
为:CURLOPT_POSTFIELDS => $param
// 测试发起多维数组的curl请求
public function actionTest() {
    $url = 'www.baidu.com';
    // 此处为二维关联数组
    $param = array('foo' => ['bar' => 'cow']);
    $data = $this->fetchApi($url, $param);
    echo json_encode($data);
    return $data;
}

// 结果会报错:Array to string conversion

报错信息以下图:
图片描述数组

若是咱们须要避免这种多维数组的问题,就须要使用http_build_query方法:curl

函数声明:函数

/** 函数做用:根据数组生成URL-encode以后的请求字符串
    @param $query_data 能够是数组或包含public属性的对象
    @param $numeric_prefix 若是数组是数字下标,会使用该值做为数字下标前缀
    @param $arg_separator 参数分割符,默认为&
    @param $enc_type URL编码规范
    @return string URL编码后的字符串
*/
string http_build_query ( mixed $query_data [, string $numeric_prefix [, string $arg_separator [, int $enc_type = PHP_QUERY_RFC1738 ]]] )

实例获取数据:post

// 一维数组
$data = array('foo', 'bar', 'baz', 'boom', 'cow' => 'milk', 'php' =>'hypertext processor');
echo http_build_query($data) . "\n";
echo http_build_query($data, 'myvar_');
// 结果:
// 0=foo&1=bar&2=baz&3=boom&cow=milk&php=hypertext+processor
// myvar_0=foo&myvar_1=bar&myvar_2=baz&myvar_3=boom&cow=milk&php=hypertext+processor

// 多维数组
$param = array('foo' => ['bar' => 'cow']);
echo http_build_query($data);
// 结果:foo%5Bbar%5D=cow 即:foo[bar]=cow

结论:

curl请求的POSTOPT_FIELDS只支持一维数组,若是是多维数组,须要使用http_build_query方法。但我推荐,为了请求的url规范化,应该所有使用http_build_queryPOST请求的参数进行编码。测试

参考资料

  1. PHP手册 CRULOPT参数:http://php.net/manual/zh/func...
  2. PHP手册 http_build_query: http://php.net/manual/zh/func...
相关文章
相关标签/搜索