今天在做一些数据统计的时候,需要获取每条数据的一些额外信息,这些信息需要通过单独请求接口获取,然而每条数据需要请求多次接口才能完整的获取所需要的信息。但是接口比较慢,每条数据多次请求接口的总时间超过30s,需要统计的几万条数据需要几十个小时的时候,显示不能接受。后来通过查找一些资料,发现php的curl支持多线程,所以后来通过改为多线程后,在半个小时的时间内就可以处理完,效率得到了很大的提高。在这里做下笔记,以便以后用到时方便查找,以下为php使用curl多线程的代码:
/**
* 多线程curl
* @param array $urls 要请求的地址
* @param array $data 请求的参数,要与urls一一对应
* @param bool $post 是否为post,默认为否
* @param int $time 超时时间
* @param array $header header头,要与urls一一对应
* @return array
*/
function curlThread($urls, $data = array(), $post = false, $time = 10, $header = array())
{
if (!$urls ||count($urls) <1) {
return array();
}
$mh = curl_multi_init();
$result = $curl = array();
foreach ($urls as $k=>$url) {
$ch = curl_init();
$options = array();
if ($post) {
$options[CURLOPT_POST] = 1;
$options[CURLOPT_POSTFIELDS] = isset($data[$k]) ? $data[$k] : array();
} else {
if (isset($data[$k]) && $data[$k]) {
$url .= '?' . http_build_query($data[$k]);
}
}
if (isset($header[$k])) {
foreach ($header[$k] as $key => $value) {
$headerArr[] = $key .':' . $value;
}
$options[CURLOPT_HTTPHEADER] = $headerArr;
}
$options[CURLOPT_RETURNTRANSFER] = true;
$options[CURLOPT_SSL_VERIFYPEER] = false; // https请求 不验证证书和hosts
$options[CURLOPT_SSL_VERIFYHOST] = false;
$options[CURLOPT_TIMEOUT] = $time;
$ch = curl_init($url);
curl_setopt_array($ch, $options);
curl_multi_add_handle($mh, $ch);
$curl[$k] = $ch;
unset($ch);
}
$active = null;
do {
$mrc = curl_multi_exec($mh, $active);
} while ($mrc == CURLM_CALL_MULTI_PERFORM); //当正在接受数据时
while ($active && $mrc == CURLM_OK) { //当无数据时或请求暂停时,active=true
if (curl_multi_select($mh) != -1) { //等待所有cURL批处理中的活动连接
usleep(100);
}
do {
$mrc = curl_multi_exec($mh, $active);
} while ($mrc == CURLM_CALL_MULTI_PERFORM);
}
foreach ($curl as $k => $v) {
if (curl_error($curl[$k]) == "") {
$result[$k] = (string) curl_multi_getcontent($curl[$k]); //获得返回信息
}
curl_multi_remove_handle($mh, $curl[$k]);
curl_close($curl[$k]);
}
curl_multi_close($mh);
return $result;
}
