本文是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的文档更加的完整。