sctq 2019-06-27
使用PHP
发起请求时,我们会常用cURL
方法,具体的PHP请求方式可以参考 PHP cURL请求详解 这篇文章。
cURL
发起POST
请求在使用中,如果你需要发送POST的请求,需要配置CURLOPT_POST
和CURLOPT_POSTFIELDS
两个参数,curl请求封装后的源码如下:
/** * 使用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
参数。
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
方法:
函数声明:
/** 函数作用:根据数组生成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 ]]] )
实例获取数据:
// 一维数组 $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_query
对POST
请求的参数进行编码。