在PHP後端的開發過程當中,除了獲取數據庫的數據和處理數據的內部邏輯,每每還須要請求其餘服務器接口的數據,咱們通常有3種方式來獲取數據,分別是:php
file_get_contents
fsockopen
curl
file_get_contents
函數聲明:html
/** 函數做用:將整個文件讀入字符串 @param $filename 讀取的文件名或url,若是是文件路徑,$use_include_path需置爲true @param $use_include_path 是否使用文件目錄路徑查找,若是是文件查找,須要置爲true,默認爲false @param $context 資源參數,使用stream_context_create創造的一個上下文,用於配置讀取文件的參數,如配置HTTP請求的方法和頭部信息 @param $offset 開始讀取數據的偏移值 @param $maxlen 從$offset開始獲取多長的數據 @return string 若是成功返回字符串,失敗返回false */ string file_get_contents(string $filename, bool $use_include_path = false, resource $context, int $offset = -1, int $maxlen)
實例獲取數據:前端
// 筆者開發使用Yii2,因此路由控制器使用action的寫法 public function actionFetch() { // 該url爲筆者寫的另一篇文章,測試用 $data = file_get_contents('https://segmentfault.com/a/1190000011549088'); // 獲取到的數據須要輸出咱們才能在前端請求看到返回的結果 echo $data; // 結束本次請求 return $data; }
fsockopen
函數聲明:數據庫
/** 函數做用:打開一個網絡鏈接或者一個Unix套接字鏈接 @param $hostname 初始化套接字鏈接到的主機 @param $port 端口號,若是不傳遞,則不實用端口 @param $errno @param $errstr 字符串形式的錯誤信息 @param $timeout 超時時間,單位爲s @return resource 若是成功返回文件句柄,可使用文件函數讀寫,失敗返回false */ resource fsockopen(string $hostname, int $port = -1, int &$errno, string &$errstr, float $timeout = ini_get("default_socket_timeout"))
實例獲取數據:json
注意:在個人測試環境中報錯:`Unable to find the socket transport "http" - did you
forget to enable it when you configured
PHP?`,是因爲php.ini配置問題,因此不推薦此種方法獲取,由於受配置文件影響,很容易不可用。
// 筆者開發使用Yii2,因此路由控制器使用action的寫法 $fp = fsockopen('https://segmentfault.com/a/1190000011549088', 80); if (!$fp) { echo "$errstr ($errno)<br />\n"; } else { $out = "GET / HTTP/1.1\r\n"; $out .= "Host: www.example.com\r\n"; $out .= "Connection: Close\r\n\r\n"; fwrite($fp, $out); while (!feof($fp)) { echo fgets($fp, 128); } fclose($fp); }
cURL
須要安裝libcurl
包。
cURL
全稱commandLine Uniform Resource Locator
,命令行統一資源定位器,用於在命令行上傳和下載url文件。提供用於程序開發的libcurl
包。
實例獲取數據:segmentfault
// 初始化一個curl資源 $ch = curl_init('https://segmentfault.com/a/1190000011549088'); // 執行該curl對象,返回結果 $data = curl_exec($ch); // 關閉cURL資源,釋放系統資源 curl_close($ch);
在代碼風格上,file_get_contents
最爲簡潔,fsockopen
和curl
比較複雜。後端
在配置頭部信息上:file_get_contents
經過stream_context_set_option()
來配置頭部信息;fsockopen
能夠經過fwirte ($socket, $config)
的方式或字符串拼接配置請求頭部信息,支持異步請求;curl
能夠經過curl_setopt($curl, $name, $key)
的方式配置請求配置,做爲lib庫,功能強大。數組
PHP不支持多進程,若是須要異步請求,非阻塞的方式,請選擇fsockopen
。
常規的請求咱們使用file_get_contents
和curl
,除了功能外,下面作一個性能測試:服務器
$url = 'https://segmentfault.com/a/1190000011549088'; // 100次file_get_contents請求,結果爲113s $start = time(); for ($i = 0; $i < 100; $i++) { $data = file_get_contents($url); } $end = time(); $cost = $end - $start; echo 'file_get_contents 100次總耗時:', "$cost"; // 100次curl請求,結果爲48s $start = time(); for ($i = 0; $i < 100; $i++) { $ch = curl_init($url); // 設置不直接輸出結果,而是保存到$data中 curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $data = curl_exec($ch); } $end = time(); $cost = $end - $start; echo 'curl 100次總耗時:', "$cost";
因此,在常規PHP請求中,咱們使用curl的方式來請求接口數據。cookie
cURL
詳解curl
的基本使用方法就是:
curl_init()
初始化cURL會話curl_setopt()
或curl_setopt_array()
設置配置選項curl_exec()
執行會話curl_close()
關閉會話curl_init()
函數聲明:
/** 函數做用:初始化curl會話 @param $url 配置中的請求url,若是不傳遞,須要在curl_setopt()設置CURLOPT_URL @return resource 若是成功返回cURL句柄,失敗返回false */ resource curl_init([string $url = NULL])
curl_setopt()
和curl_setopt_array()
函數聲明:
/** 函數做用:設置cURL傳輸選項 @param $ch curl_init()返回的cURL句柄 @param $option 須要設置的CURLOPT_XXX選項 @param $value 在option選項上設置的值 @return bool 成功返回true,失敗返回false */ bool curl_setopt(resource $ch, int $option, mixed $value) /** 函數做用:設置cURL傳輸選項 @param $ch curl_init()返回的cURL句柄 @param $options 須要設置的CURLOPT_XXX選項和值的數組 @return bool 所有成功返回true,一個失敗馬上返回false */ bool curl_setopt_array(resource $ch, array $options)
使用實例:
// 設置url和不直接輸出結果,單項設置 curl_setopt($ch, CURLOPT_URL, 'https://segmentfault.com/a/1190000011549088'); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // 批量設置 curl_setopt_array($ch, array( CURLOPT_URL => 'https://segmentfault.com/a/1190000011549088', CURLOPT_RETURNTRANSFER => true ));
CURLOPT_
參數列舉一些經常使用的參數,所有參數能夠在 PHP curl參數文檔 查閱。
CURLOPT_HEADER
啓用時會將頭文件的信息做爲數據流輸出。CURLOPT_POST
TRUE 時會發送 POST 請求,類型爲:application/x-www-form-urlencoded
,是 HTML 表單提交時最多見的一種。CURLOPT_RETURNTRANSFER
TRUE 將curl_exec()獲取的信息以字符串返回,而不是直接輸出。CURLOPT_UPLOAD
TRUE 準備上傳。CURLOPT_CONNECTTIMEOUT
在嘗試鏈接時等待的秒數。設置爲0,則無限等待。CURLOPT_PORT
用來指定鏈接端口。CURLOPT_TIMEOUT
容許 cURL 函數執行的最長秒數。CURLOPT_COOKIE
設定 HTTP 請求中"Cookie: "部分的內容。多個 cookie 用分號分隔,分號後帶一個空格(例如, "fruit=apple; colour=red")。CURLOPT_POSTFIELDS
所有數據使用HTTP協議中的 "POST" 操做來發送。該參數只支持一維數組,若是須要傳遞多維數組,須要使用http_build_query
處理,更詳細的信息能夠查看PHP cURL請求中CURLOPT_POSTFIELDS只支持一維數組這篇文章。CURLOPT_URL
須要獲取的 URL 地址,也能夠在curl_init() 初始化會話的時候。curl_exec()
函數聲明:
/** 函數做用:執行curl會話 @param $ch curl_init()返回的cURL句柄 @return mixed 成功返回true,失敗返回false;若是設置了CURLOPT_RETRUNTRANSFER爲ture,成功返回執行結果 */ mixed curl_exec(resource $ch)
curl_close()
函數聲明:
/** 函數做用:關閉curl會話 @param $ch curl_init()返回的cURL句柄 @return void */ void curl_close(resource $ch)
curl
請求封裝public static function parseApi($vars = Array(), $timeout = 60, $uri = '') { // 初始化curl $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $uri); // 支持POST請求 curl_setopt($ch, CURLOPT_POST, 1); // 不直接輸出,返回到變量 curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // 設置POST參數 curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($vars)); // 設置超時,防止機器被大量超時請求卡死 curl_setopt($ch, CURLOPT_TIMEOUT, $timeout); // 請求數據 $response = curl_exec($ch); // 關閉請求 curl_close($ch); // 對數據進行編碼,方便先後端數據處理 $result = json_decode($response, true); // PHP返回數據 return $result; }
PHP cURL
並行請求除了上面的curl_init
以外,cURL還支持curl_multi_init
並行請求,容許咱們同時請求上百個接口,而不是foreach
輪詢阻塞式的請求。詳細的能夠查看個人另外一篇文章:PHP實現併發請求。
若是你須要非阻塞的請求,可使用fsockopen()
方法。
常規的使用curl
來請求,功能強大,使用方便,按需配置。