本文是PHP and curl_multi_exec的翻譯php
這篇文章闡述瞭如何從curl_multi
句柄獲取數據。不久前,我將這段代碼片斷貼到了一個更大的示例代碼中:html
<?php $active = NULL; do { $ret = curl_multi_exec($multi, $active); } while ($ret == CURLM_CALL_MULTI_PERFORM); while ($active && $ret == CURLM_OK) { if (curl_multi_select($multi) != -1) { do { $mrc = curl_multi_exec($multi, $active); } while ($mrc == CURLM_CALL_MULTI_PERFORM); } } ?>
我以前沒有真的去查過文檔試圖理解過它。因此這段代碼讓我感到困惑。如今我來解釋下它都作了什麼。
首先,這裏有兩個外層的循環。第一個負責清除curl緩存。第二個負責等待更多的數據,而且獲取到這些數據。這就是一個典型的阻塞I/O例子。咱們阻塞住剩下程序的執行直到網絡I/O的結束。儘管這不是處理網絡I/O最合適的方法,但對於單進程、同步的PHP,這其實是咱們僅有的選擇。緩存
讓咱們先來看下第一層循環:網絡
<?php $active = NULL; do { $ret = curl_multi_exec($multi, $active); } while ($ret == CURLM_CALL_MULTI_PERFORM); ?>
curl_multi_exec
嘗試從multi句柄中獲取寫數據。$multi
是以前調用curl_multi_init()
方法產生的句柄,$active
和$ret
都是整型的值。curl_multi_exec()
把$active
設爲正在處理的句柄個數。換句話說,若是你正在用這個句柄請求5個URL,那麼curl_multi_exec
將返回5當它正在處理全部的5個URL(應該是指curl_multi_exec
設$active
爲5),而後當每一個請求結束時,這個數字將會逐漸減小直到0。curl
$ret
是以下值的一種:socket
CURLM_CALL_MULTI_PERFORM
(-1):這意味着你須要再次調用curl_multi_exec()
,由於仍有數據可供處理。CURLM_OK
(0):如文檔中所說:「都好了」。這意味着可能有更多的數據,但尚未到呢。CURLM_BAD_HANDLE
,CURLM_OUT_OF_MEMORY
,CURLM_INTERNAL_ERROR
,CURLM_BAD_SOCKET
。全部這些代表咱們須要中止處理。因此當咱們正在執行第一層循環,惟一須要咱們繼續迭代的狀況就是CURLM_CALL_MULTI_PERFORM
。url
如今,對於一些至關小的狀況,第一層循環就是你所須要的。然而一般的狀況是,第一層循環會返回CURL_OK
來代表還會有更多的數據,可是這些數據尚未在網絡上傳輸過來呢。.net
咱們須要wait。翻譯
這時候咱們就須要第二層循環:code
<?php while ($active && $ret == CURLM_OK) { if (curl_multi_select($multi) != -1) { do { $mrc = curl_multi_exec($multi, $active); } while ($mrc == CURLM_CALL_MULTI_PERFORM); } } ?>
這層循環是說...
(while): 只要有活躍的鏈接,一切還看着都OK… (if) 若是網絡socket還有些數據… (do/while) 只要系統告訴咱們要一直去獲取數據,咱們就處理吧
因此第二層循環負責檢查套接字直到一切就緒。
PHP手冊對這些東西的細節有稍微的介紹,可是libcurl C的文檔更加的完整。