curl_multi 多并发访问 封装

/**
 * curl_multi_do   并发
 * 通过curl请求一个url,data为k=v&k1=v1的格式(数组时自动整理)或post一个xml数据
 * $parameters[$url, $data, $method, $param] 对应curl_do
 **/
function curl_multi_do($parameters = []){
    $result = [];
    $ch_arr = [];
    $mh = curl_multi_init();
    // 如果使用证书则在$cert参数传入包含证书cert.pem和私钥key.pem的文件夹路径
    foreach ($parameters as $parameter) {
        $url = $parameter['url'];
        $data = $parameter['data'];
        $method = $parameter['method'];
        $param = $parameter['param'];

        if(!isset($param['cookie'])){ $param['cookie'] = false; }
        if(!isset($param['header'])){ $param['header'] = false; }
        if(!isset($param['timeout'])){ $param['timeout'] = 10; }
        if(!isset($param['need_header'])){ $param['need_header'] = false; }
        if(!isset($param['cert'])){ $param['cert'] = false; }

        $ch = curl_init();
        switch($method){
            case 'GET':
                if(is_array($data)){
                    $data_str = '';
                    if(count($data) !== 0){
                        foreach($data as $k => $v){
                            $data_str .= '&'.$k.'='.urlencode($v);
                        }
                        $data_str = substr($data_str,1);
                    }
                }else{
                    $data_str = &$data;
                }
                curl_setopt($ch,CURLOPT_URL,$url.($data_str === '' ? '' : '?'.$data_str));
                break;
            case 'POST':
                curl_setopt($ch,CURLOPT_URL,$url);
                curl_setopt($ch,CURLOPT_POST,true);
                curl_setopt($ch,CURLOPT_POSTFIELDS,$data);
                break;
            case 'PUT':
            case 'DELETE':
                curl_setopt($ch,CURLOPT_URL,$url);
                curl_setopt($ch,CURLOPT_CUSTOMREQUEST,$method);
                curl_setopt($ch,CURLOPT_POSTFIELDS,$data);
                break;
        }

        if($param['cert'] !== false){    // 如果使用证书
            // 证书和证书路径
            curl_setopt($ch,CURLOPT_SSLCERTTYPE,'PEM');
            curl_setopt($ch,CURLOPT_SSLCERT,$param['cert'].'cert.pem');
            // 私钥和私钥路径
            curl_setopt($ch,CURLOPT_SSLKEYTYPE,'PEM');
            curl_setopt($ch,CURLOPT_SSLKEY,$param['cert'].'key.pem');
        }

        if(substr($url,0,5) === 'https'){    // 如果是ssl安全请求
            curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,false);
            curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,false);
        }

        // 如果设置cookie
        if($param['cookie'] !== false){
            if(is_array($param['cookie'])){
                $cookie_str = '';
                if(count($param['cookie']) !== 0){
                    foreach($param['cookie'] as $k => $v){
                        $cookie_str .= '; '.$k.'='.$v;
                    }
                    $cookie_str = substr($cookie_str,2);
                }
                $param['cookie'] = $cookie_str;
            }
            curl_setopt($ch,CURLOPT_COOKIE,$param['cookie']);
        }

        // 如果设置header
        if($param['header'] !== false){
            curl_setopt($ch,CURLOPT_HTTPHEADER,$param['header']);
        }

        curl_setopt($ch,CURLOPT_HEADER,$param['need_header']); // 将头文件的信息作为数据流输出
        curl_setopt($ch,CURLOPT_TIMEOUT,$param['timeout']);
        curl_setopt($ch,CURLOPT_ENCODING,'');
        curl_setopt($ch,CURLOPT_RETURNTRANSFER,true);    // 要求结果为字符串且输出到屏幕

        curl_multi_add_handle($mh,$ch);
        $ch_arr[] = $ch;
    }

    $active = null;
    //execute the handles
    do {
        $mrc = curl_multi_exec($mh, $active);
    } while ($mrc == CURLM_CALL_MULTI_PERFORM);

    while ($active && $mrc == CURLM_OK) {
        if (curl_multi_select($mh) != -1) {
            do {
                $mrc = curl_multi_exec($mh, $active);
            } while ($mrc == CURLM_CALL_MULTI_PERFORM);
        }
    }

    foreach ($ch_arr as $ch) {
        $rt = [];
        $rt[1] = curl_multi_getcontent($ch);
        $rt[0] = curl_getinfo($ch,CURLINFO_HTTP_CODE);
        $rt[2] = $url;
        $rt[3] = $method;
        $rt[4] = $data;
        $rt[5] = curl_errno($ch);
        $result[] = $rt;
        curl_multi_remove_handle($mh, $ch);
    }
    curl_multi_close($mh);
    return $result;
}

 

转载于:https://www.cnblogs.com/tingfengqieyu/p/8393481.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
curlcurl_multi都是用于进行网络请求的工具。 curl是一个命令行工具,可以通过发送HTTP请求来获取网页内容或发送其他类型的网络请求。它是单线程的,在发送一个请求时会阻塞程序的执行直到请求完成并返回结果。这意味着如果要进行高并发的请求,需要启动多个curl进程来同时发送多个请求,但会造成系统资源的浪费。 而curl_multi是一个C语言库,可以实现多个网络请求的并发执行。它通过将多个curl实例放入一个集合中,并使用事件循环来处理多个请求的同时执行。这样,在发送一个请求时,程序不会阻塞,而是可以继续执行其他任务,提高了并发处理能力。当所有的请求都完成时,可以一次性获取所有的结果。这种方式减少了系统资源的浪费,提高了程序的效率。 使用curl_multi进行高并发需要注意以下几点: 1. 创建curl_multi实例,并向其中添加需要执行的curl请求。 2. 使用curl_multi_exec函数来开始执行多个请求。 3. 使用curl_multi_select函数等待请求完成。 4. 使用curl_multi_getcontent函数获取每个请求的结果。 需要注意的是,高并发的网络请求对服务器压力较大,也容易出现网络超时等问题,因此需要合理控制并发请求数量,使用适当的技术手段,如连接池、负载均衡等,来保证系统的稳定性和性能。 总之,curlcurl_multi都可以用于高并发的网络请求,但curl_multi具有更好的并发性能和资源利用率,适合在程序中进行大量请求的同时执行。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值