基於PHP的cURL快速入門3
下面的代碼有點複雜了,因此我將一小步一小步地詳細解釋:
以下為引用的內容:
// 1. 批處理器$mh = curl_multi_init();// 2. 加入需批量處理的URLfor ($i = 0; $i < $max_connections; $i++) {add_url_to_multi_handle($mh, $url_list);}// 3. 初始處理do {$mrc = curl_multi_exec($mh, $active);} while ($mrc == CURLM_CALL_MULTI_PERFORM);// 4. 主迴圈while ($active && $mrc == CURLM_OK) {// 5. 有活動串連if (curl_multi_select($mh) != -1) {// 6. 幹活do {$mrc = curl_multi_exec($mh, $active);} while ($mrc == CURLM_CALL_MULTI_PERFORM);// 7. 有資訊否?if ($mhinfo = curl_multi_info_read($mh)) {// 意味著該串連正常結束// 8. 從curl控制代碼擷取資訊$chinfo = curl_getinfo($mhinfo['handle']);// 9. 死鏈嗎?if (!$chinfo['http_code']) {$dead_urls []= $chinfo['url'];// 10. 404了?} else if ($chinfo['http_code'] == 404) {$not_found_urls []= $chinfo['url'];// 11. 還能用} else {$working_urls []= $chinfo['url'];}// 12. 移除控制代碼curl_multi_remove_handle($mh, $mhinfo['handle']);curl_close($mhinfo['handle']);// 13. 加入新URL,幹活if (add_url_to_multi_handle($mh, $url_list)) {do {$mrc = curl_multi_exec($mh, $active);} while ($mrc == CURLM_CALL_MULTI_PERFORM);}}}}// 14. 完了curl_multi_close($mh);echo "==Dead URLs==\n";echo implode("\n",$dead_urls) . "\n\n";echo "==404 URLs==\n";echo implode("\n",$not_found_urls) . "\n\n";echo "==Working URLs==\n";echo implode("\n",$working_urls);// 15. 向批處理器添加urlfunction add_url_to_multi_handle($mh, $url_list) {static $index = 0;// 如果還剩url沒用if ($url_list[$index]) {// 建立curl控制代碼$ch = curl_init();// 配置urlcurl_setopt($ch, CURLOPT_URL, $url_list[$index]);// 不想輸出返回的內容curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);// 重新導向到哪兒我們就去哪兒curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);// 不需要內容體,能夠節約頻寬和時間curl_setopt($ch, CURLOPT_NOBODY, 1);// 加入到批處理器中curl_multi_add_handle($mh, $ch);// 撥一下計數器,下次調用該函數就能添加下一個url了$index++;return true;} else {// 沒有新的URL需要處理了return false;}}
?
下面解釋一下以上代碼。列表的序號對應著代碼注釋中的順序數字。
建立一個批處理器。Created a multi handle.
稍後我們將建立一個把URL加入批處理器的函數 add_url_to_multi_handle() 。每當這個函數被調用,就有一個新url被加入批處理器。一開始,我們給批處理器添加了10個URL(這一數字由 $max_connections 所決定)。
運行 curl_multi_exec() 進行初始化工作是必須的,只要它返回 CURLM_CALL_MULTI_PERFORM 就還有事情要做。這麼做主要是為了建立串連,它不會等待完整的URL響應。
只要批處理中還有活動串連主迴圈就會一直持續。
curl_multi_select() 會一直等待,直到某個URL查詢產生活動串連。
cURL的活兒又來了,主要是擷取響應資料。
檢查各種資訊。當一個URL請求完成時,會返回一個數組。
在返回的數組中有一個 cURL 控制代碼。我們利用其擷取單個cURL請求的相應資訊。
如果這是一個死鏈或者請求逾時,不會返回http狀態代碼。
如果這個頁面找不到了,會返回404狀態代碼。
其他情況我們都認為這個連結是可用的(當然,你也可以再檢查一下500錯誤之類...)。
從該批次移除這個cURL控制代碼,因為它已經沒有利用價值了,關了它!
很好,現在可以另外加一個URL進來了。再一次地,初始化工作又開始進行...
嗯,該乾的都幹了。關閉批處理器,產生報告。
回過頭來看給批處理器添加新URL的函數。這個函數每調用一次,靜態變數 $index 就遞增一次,這樣我們才能知道還剩多少URL沒處理。
我把這個指令碼在我的部落格上跑了一遍(測試需要,有一些錯誤連結是故意加上的),結果如下:
以下為引用的內容:
?
共檢查約40個URL,只耗費兩秒不到。當需要檢查更加大量的URL時,其省心省力的效果可想而知!如果你同時開啟10個串連,還能再快上10倍!另外,你還可以利用cURL批處理的無隔斷特性來處理大量URL請求,而不會阻塞你的Web指令碼。
?
另一些有用的cURL 選項
HTTP 認證
如果某個URL請求需要基於 HTTP 的身分識別驗證,你可以使用下面的代碼:
複製內容到剪貼簿代碼:
以下為引用的內容:
$url = "http://www.somesite.com/members/";$ch = curl_init();curl_setopt($ch, CURLOPT_URL, $url);curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);// 發送使用者名稱和密碼curl_setopt($ch, CURLOPT_USERPWD, "myusername:mypassword");// 你可以允許其重新導向curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);// 下面的選項讓 cURL 在重新導向後// 也能發送使用者名稱和密碼curl_setopt($ch, CURLOPT_UNRESTRICTED_AUTH, 1);$output = curl_exec($ch);curl_close($ch);
?
FTP 上傳
PHP 內建有 FTP 類庫, 但你也能用 cURL:
以下為引用的內容:
// 開一個檔案指標$file = fopen("/path/to/file", "r");// url裡包含了大部分所需資訊$url = "ftp://username:[email protected]:21/path/to/new/file";$ch = curl_init();curl_setopt($ch, CURLOPT_URL, $url);curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);// 上傳相關的選項curl_setopt($ch, CURLOPT_UPLOAD, 1);curl_setopt($ch, CURLOPT_INFILE, $fp);curl_setopt($ch, CURLOPT_INFILESIZE, filesize("/path/to/file"));// 是否開啟ASCII模式 (上傳文字檔時有用)curl_setopt($ch, CURLOPT_FTPASCII, 1);$output = curl_exec($ch);curl_close($ch);
?
Fan牆術
你可以用代理髮起cURL請求:
以下為引用的內容:
$ch = curl_init();curl_setopt($ch, CURLOPT_URL,'http://www.example.com');curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);// 指定Proxy 位址curl_setopt($ch, CURLOPT_PROXY, '11.11.11.11:8080');// 如果需要的話,提供使用者名稱和密碼curl_setopt($ch, CURLOPT_PROXYUSERPWD,'user:pass');$output = curl_exec($ch);curl_close ($ch);
?
回呼函數
可以在一個URL請求過程中,讓cURL調用某指定的回呼函數。例如,在內容或者響應下載的過程中立刻開始利用資料,而不用等到完全下載完。
以下為引用的內容:
$ch = curl_init();curl_setopt($ch, CURLOPT_URL,'http://net.tutsplus.com');curl_setopt($ch, CURLOPT_WRITEFUNCTION,"progress_function");curl_exec($ch);curl_close ($ch);function progress_function($ch,$str) {echo $str;return strlen($str);}?
這個回呼函數必須返回字串的長度,不然此功能將無法正常使用。
在URL響應接收的過程中,只要收到一個資料包,這個函數就會被調用。
小結
今天我們一起學習了cURL庫的強大功能和靈活的擴充性。希望你喜歡。下一次要發起URL請求時,考慮下cURL吧!
原文:基於PHP的cURL快速入門
英文原文:http://net.tutsplus.com/tutorial%20...%20for-mastering-curl/
原文作者:Burak Guzel
本文連結:http://www.blueidea.com/tech/program/2010/7348.asp