我不生产代码
我只是代码的搬运工

php实现curl多线程

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

本文章为本站原创,如转载请注明文章出处:https://www.sviping.com/archives/32

分享到:
上一篇: 详解 awk 工具的使用方法 下一篇: centos7.0中将php5.6到php7最新版本
12