curl_multi
同时请求多个url,而不是一个一个依次请求。
步骤总结如下:
1. 调用curl_multi_init
2. 循环调用curl_multi_add_handle(这一步需要注意的是,curl_multi_add_handle的第二个参数是由curl_init而来的子handle)。
3. 持续调用curl_multi_exec
4. 根据需要循环调用curl_multi_getcontent获取结果
5. 调用curl_multi_remove_handle,并为每个子handle调用curl_close
6. 调用curl_multi_close
resource curl_multi_init(void)
允许并行地处理批处理cURL句柄。成功时返回一个cURL批处理句柄,失败时返回FALSE.
int curl_multi_add_handle(resource $mh, resource $ch)
增加ch句柄到批处理会话mh
参数:mh 由curl_multi_init()返回的cURL多个句柄。
ch 由curl_init()返回的cURL句柄。
成功时返回0,失败时返回CURLM_XXX之一的错误码。
int curl_multi_exec(resource $mh, int &$still_running)
处理在栈中的每一个句柄。无论该句柄需要读取或写入数据都可调用此方法。
mh 由curl_multi_init()返回的cURL多个句柄。
still_running 一个用来判断操作是否仍在执行的标识的引用。
返回值
一个定义于cURL预定义常量中的cURL代码。
注意:该函数仅返回关于整个批处理栈相关的错误。即使返回CURLM_OK时单个传输仍可能有问题。
curl_multi_exec在底层调用了libcurl的curl_multi_perform函数。在curl7.20.0以前,此函数会返回一个CURLM_CALL_MULTI_PERFORM值,代表它希望立刻再一次被调用。所以就有了检查此返回值,再一次调用curl_multi_exec函数的demo。在7.20.0之后,libcurl把这个工作自己在内部做了,所以就不用应用端再做了,直接调用curl_multi_exec,只检查$still_running参数就行了。
string curl_multi_getcontent(resource $ch)
如果CURLOPT_RETURNTRANSFER作为一个选项被设置到一个具体的句柄,那么这个函数将会以字符串的形式返回那个cURL句柄获取的内容。
ch 由curl_init()返回的cURL句柄。
Int curl_multi_select(resource $mh)
阻塞直到cURL批处理连接中有活动连接。
返回值
成功时返回描述符集合中描述符的数量。失败时,select失败时返回-1,否则返回超时(从底层的select系统调用)。
这个范例将会创建2个cURL句柄,把它们加到批处理句柄,然后并行地运行它们。
//创建一对cURL资源
$ch1=curl_init();
$ch2=curl_init();
//设置URL和相应的选项
curl_setopt($ch1, CURLOPT_URL, "http://404.122.195.246:8089/isactive");
curl_setopt($ch1, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch1, CURLOPT_HEADER, false);
curl_setopt($ch1, CURLOPT_URL, "http://404.122.195.245:8089/isactive");
curl_setopt($ch1, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch1, CURLOPT_HEADER, false);
//创建批处理cURL句柄
$mh=curl_multi_init();
//增加2个句柄
curl_multi_add_handle($mh, $ch1);
curl_multi_add_handle($mh, $ch2);
$running=null;
//执行批处理句柄
do{
usleep(10000);
curl_multi_exec($mh, $running);
}while($running>0);
//关闭全部句柄
curl_multi_remove_handle($mh, $ch1);
curl_multi_remove_handle($mh, $ch2);
curl_multi_close($mh);
批处理
$aUrls=array(
"http://402.112.195.246:8089",
"http://2.112.195.246:8092",
"http://2.112.195.245:8095",
"http://2.112.195.246:8094"
);
$mh=curl_multi_init();
$aCurlHandles=array();
foreach ($aUrls as $id=>$url){
$url=$url.'/isactive';
$ch=curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_TIMEOUT_MS, 10000);
$aCurlHandles[$url]=$ch;
curl_multi_add_handle($mh, $ch);
}
$active=null;
//执行批处理句柄
do{
$mrc=curl_multi_exec($mh, $active);
}
while($mrc==CURLM_CALL_MULTI_PERFORM);
while($active && $mrc==CURLM_OK){
if(curl_multi_select($mh)==-1){
echo "error<br/>";
usleep(5000);
}
do{
$mrc=curl_multi_exec($mh, $active);
}while($mrc==CURLM_CALL_MULTI_PERFORM);
}
/*usleep(10000);*/
foreach($aCurlHandles as $url=>$ch){
$html=curl_multi_getcontent($ch);
echo $url.'----'.$html.'<br/>';
curl_multi_remove_handle($mh, $ch);
}
curl_multi_close($mh);