cURL批處理(multi cURL)
cURL還有一個高級特性——批處理句柄(handle)。這一特性允許你同時或異步地打開多個URL連接。
下面是來自來自php.net的示例代碼:
// 創(chuàng)建兩個cURL資源 $ch1 = curl_init(); $ch2 = curl_init(); // 指定URL和適當(dāng)?shù)膮?shù) curl_setopt($ch1, CURLOPT_URL, "curl_setopt($ch1, CURLOPT_HEADER, 0); curl_setopt($ch2, CURLOPT_URL, "curl_setopt($ch2, CURLOPT_HEADER, 0); // 創(chuàng)建cURL批處理句柄 $mh = curl_multi_init(); // 加上前面兩個資源句柄 curl_multi_add_handle($mh,$ch1); curl_multi_add_handle($mh,$ch2); // 預(yù)定義一個狀態(tài)變量 $active = null; // 執(zhí)行批處理 do { $mrc = curl_multi_exec($mh, $active); } while ($mrc == CURLM_CALL_MULTI_PERFORM); while ($active && $mrc == CURLM_OK) { if (curl_multi_select($mh) != -1) { do { $mrc = curl_multi_exec($mh, $active); } while ($mrc == CURLM_CALL_MULTI_PERFORM); } } // 關(guān)閉各個句柄 curl_multi_remove_handle($mh, $ch1); curl_multi_remove_handle($mh, $ch2); curl_multi_close($mh);
這里要做的就是打開多個cURL句柄并指派給一個批處理句柄。然后你就只需在一個while循環(huán)里等它執(zhí)行完畢。
這個示例中有兩個主要循環(huán)。第一個 do-while 循環(huán)重復(fù)調(diào)用 curl_multi_exec() 。這個函數(shù)是無隔斷(non-blocking)的,但會盡可能少地執(zhí)行。它返回一個狀態(tài)值,只要這個值等于常量 CURLM_CALL_MULTI_PERFORM ,就代表還有一些刻不容緩的工作要做(例如,把對應(yīng)URL的http頭信息發(fā)送出去)。也就是說,我們需要不斷調(diào)用該函數(shù),直到返回值發(fā)生改變。
而接下來的 while 循環(huán),只在 $active 變量為 true 時繼續(xù)。這一變量之前作為第二個參數(shù)傳給了 curl_multi_exec() ,代表只要批處理句柄中是否還有活動連接。接著,我們調(diào)用 curl_multi_select() ,在活動連接(例如接受服務(wù)器響應(yīng))出現(xiàn)之前,它都是被“屏蔽”的。這個函數(shù)成功執(zhí)行后,我們又會進入另一個 do-while 循環(huán),繼續(xù)下一條URL。
還是來看一看怎么把這一功能用到實處吧:
WordPress 連接檢查器
想象一下你有一個文章數(shù)目龐大的博客,這些文章中包含了大量外部網(wǎng)站鏈接。一段時間之后,因為這樣那樣的原因,這些鏈接中相當(dāng)數(shù)量都失效了。要么是被和諧了,要么是整個站點都被功夫網(wǎng)了...
我們下面建立一個腳本,分析所有這些鏈接,找出打不開或者404的網(wǎng)站/網(wǎng)頁,并生成一個報告。
請注意,以下并不是一個真正可用的WordPress插件,僅僅是一段獨立功能的腳本而已,僅供演示,謝謝。
好,開始吧。首先,從數(shù)據(jù)庫中讀取所有這些鏈接:
// CONFIG $db_host = 'localhost'; $db_user = 'root'; $db_pass = ''; $db_name = 'wordpress'; $excluded_domains = array( 'localhost', 'www.mydomain.com'); $max_connections = 10; // 初始化一些變量 $url_list = array(); $working_urls = array(); $dead_urls = array(); $not_found_urls = array(); $active = null; // 連到 MySQL if (!mysql_connect($db_host, $db_user, $db_pass)) { die('Could not connect: ' . mysql_error()); } if (!mysql_select_db($db_name)) { die('Could not select db: ' . mysql_error()); } // 找出所有含有鏈接的文章 $q = "SELECT post_content FROM wp_posts WHERE post_content LIKE '%href=%' AND post_status = 'publish' AND post_type = 'post'"; $r = mysql_query($q) or die(mysql_error()); while ($d = mysql_fetch_assoc($r)) { // 用正則匹配鏈接 if (preg_match_all("!href=\"(.*?)\"!", $d['post_content'], $matches)) { foreach ($matches[1] as $url) { // exclude some domains $tmp = parse_url($url); if (in_array($tmp['host'], $excluded_domains)) { continue; } // store the url $url_list []= $url; } } } // 移除重復(fù)鏈接 $url_list = array_values(array_unique($url_list)); if (!$url_list) { die('No URL to check'); }
我們首先配置好數(shù)據(jù)庫,一系列要排除的域名($excluded_domains),以及最大并發(fā)連接數(shù)($max_connections)。然后,連接數(shù)據(jù)庫,獲取文章和包含的鏈接,把它們收集到一個數(shù)組中($url_list)。
出處:藍色理想
責(zé)任編輯:moby
上一頁 基于PHP的cURL快速入門 [3] 下一頁 基于PHP的cURL快速入門 [5]
◎進入論壇網(wǎng)絡(luò)編程版塊參加討論
|