php curl_multi批量傳送http請求
一、使用curl_multi批量傳送http請求
引子:在Android4.0開發中,傳送Http請求已經不允許在主程式中執行了,必須線上程中執行。原因在於Http介面響應時間有可能阻塞主程式事件監聽(對於.Net開發,其實也是如此)。但是,由於PHP並沒有多執行緒的概念,那麼,如何高效率在PHP中執行多次http請求呢?答案是使用curl_multi_init,由此,我做了一個實驗。
以下是模擬請求的http介面,程式碼很簡單,通過get傳入的引數time,控制了sleep的時間。
$s_time = intval($_GET['time']);
sleep($s_time);
echo 'hello';
接下來僅僅使用curl_init,程式碼如下:
$start = microtime(true);
for ($i = 1;$i <= 5;++$i) {
$ch = curl_init("http://test.binbin.com/curl/test.php?time={$i}");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_exec($ch);
}
$end = microtime(true);
echo $end-$start;
執行的時間約為15秒,是所有sleep時間總和,現在,來看看使用了curl_multi_init的時間
$start = microtime(true);
$ch_list = array();
$multi_ch = curl_multi_init();
for ($i = 1;$i <= 5;++$i) {
$ch_list[$i] = curl_init("http://test.binbin.com/curl/test.php?time={$i}");
curl_setopt($ch_list[$i], CURLOPT_RETURNTRANSFER, true);
curl_multi_add_handle($multi_ch, $ch_list[$i]);
}
$active = null;
do {
$mrc = curl_multi_exec($multi_ch, $active); //處理在棧中的每一個控制程式碼。無論該控制程式碼需要讀取或寫入資料都可呼叫此方法。
} while ($mrc == CURLM_CALL_MULTI_PERFORM);
//Note:
//該函式僅返回關於整個批處理棧相關的錯誤。即使返回 CURLM_OK 時單個傳輸仍可能有問題。
while ($active && $mrc == CURLM_OK) {
if (curl_multi_select($multi_ch) != -1) { //阻塞直到cURL批處理連線中有活動連線。
do {
$mrc = curl_multi_exec($multi_ch, $active);
} while ($mrc == CURLM_CALL_MULTI_PERFORM);
}
}
//獲取http返回的結果
foreach ($ch_list as $k => $ch) {
$result=curl_multi_getcontent($ch);
curl_multi_remove_handle($multi_ch,$ch);
curl_close($ch);
}
curl_multi_close($multi_ch);
$end = microtime(true);
echo $end-$start;
結果是僅僅需要5秒鐘,即使最長http請求的執行時間。
後記:curl_errno在curl_multi下即使發生錯誤也無法獲取錯誤碼,可以使用curl_error來獲取錯誤字串,如果沒有發生錯誤,則返回一個空的字串
二、curlmulti系列函式說明
函式名稱 | 函式說明 |
curl_multi_init | 返回一個新的curl_multi資源控制程式碼,失敗時返回false |
curl_multi_add_handle | 向curl批處理會話中新增單獨的curl控制程式碼 |
curl_multi_exec | 執行當前 cURL 控制程式碼的子連線 |
curl_multi_select | 等待所有cURL批處理中的活動連線,成功時返回描述符集合中描述符的數量。失敗時,select失敗時返回-1。 |
curl_multi_getcontent | 獲取curl控制程式碼的返回結果內容 |
curl_multi_close | 關閉一個curl_multi資源控制程式碼 |
curl_multi_info_read | 獲取當前解析的cURL的相關傳輸資訊 |
相關文章
- 【轉】怎麼用PHP傳送HTTP請求(POST請求、GET請求)?PHPHTTP
- PHP 傳送 HTTP 請求的幾種方式PHPHTTP
- perl傳送http請求HTTP
- java傳送http請求JavaHTTP
- 使用httpclient傳送http請求HTTPclient
- 使用Feign傳送HTTP請求HTTP
- python傳送HTTP POST請求PythonHTTP
- .net 後臺 傳送http請求HTTP
- PHP傳送POST和GET請求PHP
- 使用requests庫來傳送HTTP請求HTTP
- nodejs使用request傳送http請求NodeJSHTTP
- java傳送http的get、post請求JavaHTTP
- php 利用socket傳送GET,POST請求PHP
- Go使用net/http庫傳送GET請求GoHTTP
- Go HTTP GET 請求可以傳送 body 嗎GoHTTP
- Windows Phone 8.1 傳送http 網路請求。WindowsHTTP
- DDD:聚合根的批量刪除是不是可以批量傳送請求
- 理解ASP.NET Core - 傳送Http請求(HttpClient)ASP.NETHTTPclient
- wireshark抓包curl傳送http2請求HTTP
- 使用 request 和 cheerio 庫來傳送 HTTP 請求HTTP
- oracle使用utl_http包傳送post請求OracleHTTP
- 在Java中,使用HttpUtils實現傳送HTTP請求JavaHTTP
- Jmeter —— jmeter利用取樣器中http傳送請求JMeterHTTP
- cURL實現傳送Get和Post請求(PHP)PHP
- Postman傳送Post請求Postman
- Java傳送Post請求Java
- 傳送GET請求 示例
- HttpClient--傳送請求HTTPclient
- HTTP GET請求傳bodyHTTP
- 如何傳送請求以及AJAX
- C# 傳送POST請求C#
- 使用HttpClient傳送GET請求HTTPclient
- 【python介面自動化】- 使用requests庫傳送http請求PythonHTTP
- 如何檢視 Chrome 外掛傳送的 HTTP 請求(或 localStorage)?ChromeHTTP
- 在ASP.NET Core中用HttpClient(三)——傳送HTTP PATCH請求ASP.NETHTTPclient
- Delphi 通過IdHTTP 傳送Http請求到Java 後臺HTTPJava
- Golang:使用go-resty/resty傳送http請求get和postGolangRESTHTTP
- SpringMVC中如何傳送GET請求、POST請求、PUT請求、DELETE請求。SpringMVCdelete