今天在做一些数据统计的时候,需要获取每条数据的一些额外信息,这些信息需要通过单独请求接口获取,然而每条数据需要请求多次接口才能完整的获取所需要的信息。但是接口比较慢,每条数据多次请求接口的总时间超过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; }