php中的curl_multi系列函數(shù)使用例子
相信許多人對php手冊中語焉不詳?shù)腸url_multi一族的函數(shù)頭疼不已,它們文檔少,給的例子 更是簡單的讓你無從借鑒,我也曾經(jīng)找了許多網(wǎng)頁,都沒見一個(gè)完整的應(yīng)用例子。
- curl_multi_add_handle
- curl_multi_close
- curl_multi_exec
- curl_multi_getcontent
- curl_multi_info_read
- curl_multi_init
- curl_multi_remove_handle
- curl_multi_select
一般來說,想到要用這些函數(shù)時(shí),目的顯然應(yīng)該是要同時(shí)請求多個(gè)url,而不是一個(gè)一個(gè)依次請求,否則不如自己循環(huán)去調(diào)curl_exec好了。
步驟總結(jié)如下:
第一步:調(diào)用curl_multi_init
第二步:循環(huán)調(diào)用curl_multi_add_handle
這一步需要注意的是,curl_multi_add_handle的第二個(gè)參數(shù)是由curl_init而來的子handle。
第三步:持續(xù)調(diào)用curl_multi_exec
第四步:根據(jù)需要循環(huán)調(diào)用curl_multi_getcontent獲取結(jié)果
第五步:調(diào)用curl_multi_remove_handle,并為每個(gè)字handle調(diào)用curl_close
第六步:調(diào)用curl_multi_close
這里有一個(gè)網(wǎng)上找的簡單例子,其作者稱為dirty的例子,(稍后我會說明為何dirty):
/*
Here's a quick and dirty example for curl-multi from PHP, tested on PHP 5.0.0RC1 CLI / FreeBSD 5.2.1
*/
$connomains = array(
"http://www.baidu.com/",
"http://www.google.com/",
"http://www.dhdzp.com/"
);
$mh = curl_multi_init();
foreach ($connomains as $i => $url) {
$conn[$i]=curl_init($url);
curl_setopt($conn[$i],CURLOPT_RETURNTRANSFER,1);
curl_multi_add_handle ($mh,$conn[$i]);
}
do { $n=curl_multi_exec($mh,$active); } while ($active);
foreach ($connomains as $i => $url) {
$res[$i]=curl_multi_getcontent($conn[$i]);
curl_close($conn[$i]);
}
print_r($res);
整個(gè)使用過程差不多就是這樣,但是,這個(gè)簡單代碼有個(gè)致命弱點(diǎn),就是在do循環(huán)的那段,在整個(gè)url請求期間是個(gè)死循環(huán),它會輕易導(dǎo)致CPU占用100%。
現(xiàn)在我們來改進(jìn)它,這里要用到一個(gè)幾乎沒有任何文檔的函數(shù)curl_multi_select了,雖然C的curl庫對select有說明,但是,php里的接口和用法確與C中有不同。
把上面do的那段改成下面這樣:
do {
$mrc = curl_multi_exec($mh,$active);
} while ($mrc == CURLM_CALL_MULTI_PERFORM);
while ($active and $mrc == CURLM_OK) {
if (curl_multi_select($mh) != -1) {
do {
$mrc = curl_multi_exec($mh, $active);
} while ($mrc == CURLM_CALL_MULTI_PERFORM);
}
}
因?yàn)?active要等全部url數(shù)據(jù)接受完畢才變成false,所以這里用到了curl_multi_exec的返回值判斷是否還有數(shù)據(jù),當(dāng)有數(shù)據(jù)的時(shí)候就不停調(diào)用curl_multi_exec,暫時(shí)沒有數(shù)據(jù)就進(jìn)入select階段,新數(shù)據(jù)一來就可以被喚醒繼續(xù)執(zhí)行。這里的好處就是CPU的無謂消耗沒有了。
另外:還有一些細(xì)節(jié)的地方可能有時(shí)候要遇到:
控制每一個(gè)請求的超時(shí)時(shí)間,在curl_multi_add_handle之前通過curl_setopt去做:
判斷是否超時(shí)了或者其他錯誤,在curl_multi_getcontent之前用:curl_error($conn[$i]);
- PHP使用CURL_MULTI實(shí)現(xiàn)多線程采集的例子
- 解析php中curl_multi的應(yīng)用
- PHP使用curl_multi實(shí)現(xiàn)并發(fā)請求的方法示例
- php curl post 時(shí)出現(xiàn)的問題解決
- 關(guān)于PHP的curl開啟問題探討
- php使用curl詳細(xì)解析及問題匯總
- PHP CURL 內(nèi)存泄露問題解決方法
- php5.2的curl-bug 服務(wù)器被php進(jìn)程卡死問題排查
- php中curl和soap方式請求服務(wù)超時(shí)問題的解決
- PHP使用curl_multi_select解決curl_multi網(wǎng)頁假死問題的方法
相關(guān)文章
ajax調(diào)用返回php接口返回json數(shù)據(jù)的方法(必看篇)
下面小編就為大家?guī)硪黄猘jax調(diào)用返回php接口返回json數(shù)據(jù)的方法(必看篇)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-05-05
php獲取小程序碼的實(shí)現(xiàn)代碼(B類接口)
這篇文章主要介紹了php獲取小程序碼的實(shí)現(xiàn)代碼(B類接口),需要的朋友可以參考下2020-06-06
ECshop 遷移到 PHP7版本時(shí)遇到的兼容性問題
最近有網(wǎng)友問我在php7上安裝ecshopv2.7.3時(shí),報(bào)錯,究竟了半天沒有找到原因,下面由腳本之家小編給大家分析此問題出現(xiàn)的原因2016-02-02
關(guān)于PhpStorm設(shè)置點(diǎn)擊編輯文件自動定位源文件的實(shí)現(xiàn)方式
這篇文章主要介紹了關(guān)于PhpStorm設(shè)置點(diǎn)擊編輯文件自動定位源文件的實(shí)現(xiàn)方式,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-12-12
關(guān)于PHP中字符串與多進(jìn)制轉(zhuǎn)換函數(shù)的實(shí)例代碼
下面小編就為大家?guī)硪黄P(guān)于PHP中字符串與多進(jìn)制轉(zhuǎn)換函數(shù)的實(shí)例代碼。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2016-11-11
PHP實(shí)現(xiàn)頁面靜態(tài)化深入講解
這篇文章主要介紹了PHP實(shí)現(xiàn)頁面靜態(tài)化深入講解,本文講解的很透徹,有感興趣的同學(xué)可以研究下2021-03-03
php腳本運(yùn)行時(shí)的超時(shí)機(jī)制詳解
在我們平常的開發(fā)中,也許曾經(jīng)都遇到過PHP腳本運(yùn)行超時(shí)的情況,當(dāng)遇到這種情況我們經(jīng)常會通過使用 set_time_limit(非安全模式),或修改配置文件并重啟服務(wù)器,或者修改程序減少程序的執(zhí)行時(shí)間,使其在允許的范圍之內(nèi),以解決此問題。2016-02-02

