栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > PHP

PHP CURL 实现并发访问网络资源

PHP 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

PHP CURL  实现并发访问网络资源


  1. PHP cURL 所有函数列表:

  2. http://php.net/manual/zh/ref.curl.php


以下是PHP中cURL多线程相关函数:

curl_multi_add_handle — 向curl批处理会话中添加单独的curl句柄

curl_multi_close — 关闭一组cURL句柄

curl_multi_exec — 运行当前 cURL 句柄的子连接

curl_multi_getcontent — 如果设置了CURLOPT_RETURNTRANSFER,则返回获取的输出的文本流

curl_multi_info_read — 获取当前解析的cURL的相关传输信息

curl_multi_init — 返回一个新cURL批处理句柄

curl_multi_remove_handle — 移除curl批处理句柄资源中的某个句柄资源

curl_multi_select — 等待所有cURL批处理中的活动连接

curl_multi_setopt — 为 cURL 并行处理设置一个选项

curl_multi_strerror — Return string describing error code

一般来说,想到要用这些函数时,目的显然应该是要同时请求多个URL,而不是一个一个依次请求,否则不如自己循环去调curl_exec好了。

步骤总结如下:

1、调用 curl_multi_init,初始化一个批处理handle
2、循环调用 curl_multi_add_handle,往1中的批处理handle 添加curl_init来的子handle
3、持续调用 curl_multi_exec,直到所有子handle执行完毕。
4、根据需要循环调用 curl_multi_getcontent 获取结果
5、调用 curl_multi_remove_handle,并为每个字handle调用curl_close
6、调用 curl_multi_close


 

 

function cmi($connomains, $killspace = TRUE, $forhtml = TRUE, $timeout = 6, $header = 0, $follow = 1) {

 

 

    $res = array();

    $urlsa = array();

    $results = array();

    $mh = curl_multi_init(); //创建多curl对象,为了几乎同时执行

    foreach ($connomains as $i => $url) {

        $conn[$i] = curl_init($url); //若url中含有gb2312汉字,例如FTP时,要在传入url的时候处理一下,这里不用

        curl_setopt($conn[$i], CURLOPT_TIMEOUT, $timeout); //此时间须根据页面的HTML源码出来的时间,一般是在1s内的,慢的话应该也不会6秒,极慢则是在16秒内

        curl_setopt($conn[$i], CURLOPT_HEADER, $header); //不返回请求头,只要源码

        curl_setopt($conn[$i], CURLOPT_RETURNTRANSFER, 1); //必须为1

        curl_setopt($conn[$i], CURLOPT_FOLLOWLOCATION, $follow); //如果页面含有自动跳转的代码如301或者302HTTP时,自动拿转向的页面

        curl_multi_add_handle($mh, $conn[$i]); //关键,一定要放在上面几句之下,将单curl对象赋给多对象

    }

    //下面一大步的目的是为了减少cpu的无谓负担,暂时不明,来自php.net的建议,几乎是固定用法

    do {

        $mrc = curl_multi_exec($mh, $active); //当无数据时或请求暂停时,active=true

    } while ($mrc == CURLM_CALL_MULTI_PERFORM); //当正在接受数据时

    while ($active and $mrc == CURLM_OK) {//当无数据时或请求暂停时,active=true,为了减少cpu的无谓负担,这一步很难明啊

        if (curl_multi_select($mh) != -1) {

            do {

                $mrc = curl_multi_exec($mh, $active);

            } while ($mrc == CURLM_CALL_MULTI_PERFORM);

        }

    }

    /////////////////////////////////////////////////////////////////////////////////////////

//下面返回结果

    foreach ($connomains as $i => $url) {

        $cinfo = curl_getinfo($conn[$i]); //可用于取得一些有用的参数,可以认为是header

        $url = $cinfo[url]; //真实url,有些url

        if ($killspace) {//有点水消耗

            $str = trim(curl_multi_getcontent($conn[$i]));

            $str = preg_replace('/s(?=s)/', '', $str); //去掉跟随别的挤在一块的空白       

            $str = preg_replace('/[nrt]/', ' ', $str);  //最后,去掉非space 的空白,用一个空格代替

            $res[$i] = stripslashes($str); //取得对象源码,并取消换行,节约内存的同时,可以方便作正则处理

        } else {

            $res[$i] = curl_multi_getcontent($conn[$i]);

        }

        if (!$forhtml) {//节约内存

            $res[$i] = NULL;

        }

       

        curl_close($conn[$i]); //关闭所有对象

        curl_multi_remove_handle($mh, $conn[$i]);   //用完马上释放资源              

    }

    curl_multi_close($mh);

    $mh = NULL;

    $conn = NULL;

 

    return $res;

}

 

//cmi 下面是版本二,几乎一至的代码,但输出的形式改为为带key;

function cmi($connomains, $killspace = TRUE, $forhtml = TRUE, $timeout = 6, $header = 0, $follow = 1) {

 

 

    $res = array(); //用于保存结果     

//$connomains=array_flip(array_flip($connomains));//去除url中的重复项

    $mh = curl_multi_init(); //创建多curl对象,为了几乎同时执行

    foreach ($connomains as $i => $url) {

        $conn[$url] = curl_init($url); //若url中含有gb2312汉字,例如FTP时,要在传入url的时候处理一下,这里不用

        //此时间须根据页面的HTML源码出来的时间,一般是在1s内的,慢的话应该也不会6秒,极慢则是在16秒内

        curl_setopt($conn[$url], CURLOPT_TIMEOUT, $timeout); 

        curl_setopt($conn[$url], CURLOPT_HEADER, $header); //不返回请求头,只要源码

        curl_setopt($conn[$url], CURLOPT_RETURNTRANSFER, 1); //必须为1

        //如果页面含有自动跳转的代码如301或者302HTTP时,自动拿转向的页面

        curl_setopt($conn[$url], CURLOPT_FOLLOWLOCATION, $follow); 

        curl_multi_add_handle($mh, $conn[$url]); //关键,一定要放在上面几句之下,将单curl对象赋给多对象

    }

    //下面一大步的目的是为了减少cpu的无谓负担,暂时不明,来自php.net的建议,几乎是固定用法

    do {

        $mrc = curl_multi_exec($mh, $active); //当无数据时或请求暂停时,active=true

    } while ($mrc == CURLM_CALL_MULTI_PERFORM); //当正在接受数据时

    while ($active and $mrc == CURLM_OK) {//当无数据时或请求暂停时,active=true,为了减少cpu的无谓负担,这一步很难明啊

        if (curl_multi_select($mh) != -1) {

            do {

                $mrc = curl_multi_exec($mh, $active);

            } while ($mrc == CURLM_CALL_MULTI_PERFORM);

        }

    }

    /////////////////////////////////////////////////////////////////////////////////////////

//下面返回结果

    foreach ($connomains as $i => $url) {

        $cinfo = curl_getinfo($conn[$url]); //可用于取得一些有用的参数,可以认为是header

        //$url=$cinfo[url];//真实url,有些url

        if ($killspace) {//有点水消耗

            $str = trim(curl_multi_getcontent($conn[$url]));

            $str = preg_replace('/s(?=s)/', '', $str); //去掉跟随别的挤在一块的空白       

            $str = preg_replace('/[nrt]/', ' ', $str);  //最后,去掉非space 的空白,用一个空格代替

            $res[$url] = stripslashes($str); //取得对象源码,并取消换行,节约内存的同时,可以方便作正则处理

        } else {

            $res[$url] = curl_multi_getcontent($conn[$url]);

        }

        if (!$forhtml) {//节约内存

            $res[$url] = NULL;

        }

       

        curl_close($conn[$url]); //关闭所有对象 

        curl_multi_remove_handle($mh, $conn[$url]);   //用完马上释放资源              

    }

    curl_multi_close($mh);

    $mh = NULL;

    $conn = NULL;

    $connomains = NULL;

 

    return $res;

}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/227746.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号