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...
相關文章
相關標籤/搜索