通过curl库的curl

    技术2022-05-14  1

    http://www.trackself.com/code/curl_multi.html function cmi($connomains,$killspace=TRUE,$forhtml=TRUE,$timeout=6,$header=0,$follow=1){ /* cmi该函数的目的在于并发请求多个url,然后返回http://www.trackself.com 编写,真正的PHP并发 原文发表在http://www.trackself.com/archives/463.html 此并发请求在url多于2的时候,明显比for ... file_get_contents ...要优很多 核心是curl库的curl_multi方法 用法: $urls=array( 'http://www.google.com', 'http://www.baidu.com', 'http://sina.com', 'http://163.com' ) $htmls=cmi($urls); print_r($htmls); //传入的$connomains是URL一维数组,由http://www.trackself.com编写 //该函数的目的在于并发请求多个url,然后返回源码 //以一次性略增加CPU为代价 //来减轻服务器因为for ... file_get_contents ...的长时连接负担及内存和CPU的负担,所以并发数不要大多(50以内效果非常好),尽量不要用于单页面或3页面以内的请求 //$killspace为真时表示自动去掉HTML中换行及多余的空白,$forhtml为真时表示反回源码,为faluse时就是并发执行请求了(可以用于计划任务) //后面的几个参数的详细说明请看注释,毕竟函数不长 */ $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('/[/n/r/t]/', ' ', $str); //最后,去掉非space 的空白,用一个空格代替 $res[$i]=stripslashes($str);//取得对象源码,并取消换行,节约内存的同时,可以方便作正则处理 }else{ $res[$i]=curl_multi_getcontent($conn[$i]); } if(!$forhtml){//节约内存 $res[$i]=NULL; } /*下面这一段放一些高消耗的程序代码,用来处理HTML,我保留的一句=NULL是要提醒,及时清空对象释放内存,此程序在并发过程中如果源码太大,内在消耗严重 //事实上,这里应该做一个callback函数或者你应该将你的逻辑直接放到这里来,我为了程序可重复,没这么做 preg_match_all($preg,$res[$i],$matchlinks); $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){ /* cmi该函数的目的在于并发请求多个url,然后返回http://www.trackself.com 编写,真正的PHP并发 原文发表在http://www.trackself.com/archives/463.html 此并发请求在url多于2的时候,明显比for ... file_get_contents ...要优很多 核心是curl库的curl_multi方法 用法: //array_flip(array_flip($connomains)) $urls=array( 'http://www.google.com', 'http://www.baidu.com', 'http://sina.com', 'http://163.com' ) $urls=array_flip(array_flip($connomains));//去除url中的重复的项,注意传入urls时一定要系合法的url表达,虽然不会影响其它url执行,但会减慢执行速度 $htmls=cmi($urls); print_r($htmls); //传入的$connomains是URL一维数组,由http://www.trackself.com编写 //该函数的目的在于并发请求多个url,然后返回源码 //以一次性略增加CPU为代价 //来减轻服务器因为for ... file_get_contents ...的长时连接负担及内存和CPU的负担,所以并发数不要大多(50以内效果非常好),尽量不要用于单页面或3页面以内的请求 //$killspace为真时表示自动去掉HTML中换行及多余的空白,$forhtml为真时表示反回源码,为faluse时就是并发执行请求了(可以用于计划任务) //后面的几个参数的详细说明请看注释,毕竟函数不长 */ $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的时候处理一下,这里不用 curl_setopt($conn[$url], CURLOPT_TIMEOUT, $timeout);//此时间须根据页面的HTML源码出来的时间,一般是在1s内的,慢的话应该也不会6秒,极慢则是在16秒内 curl_setopt($conn[$url], CURLOPT_HEADER, $header);//不返回请求头,只要源码 curl_setopt($conn[$url],CURLOPT_RETURNTRANSFER,1);//必须为1 curl_setopt($conn[$url], CURLOPT_FOLLOWLOCATION, $follow);//如果页面含有自动跳转的代码如301或者302HTTP时,自动拿转向的页面 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('/[/n/r/t]/', ' ', $str); //最后,去掉非space 的空白,用一个空格代替 $res[$url]=stripslashes($str);//取得对象源码,并取消换行,节约内存的同时,可以方便作正则处理 }else{ $res[$url]=curl_multi_getcontent($conn[$url]); } if(!$forhtml){//节约内存 $res[$url]=NULL; } /*下面这一段放一些高消耗的程序代码,用来处理HTML,我保留的一句=NULL是要提醒,及时清空对象释放内存,此程序在并发过程中如果源码太大,内在消耗严重 //事实上,这里应该做一个callback函数或者你应该将你的逻辑直接放到这里来,我为了程序可重复,没这么做 preg_match_all($preg,$res[$i],$matchlinks); $res[$i]=NULL; */ curl_close($conn[$url]);//关闭所有对象 curl_multi_remove_handle($mh , $conn[$url]); //用完马上释放资源 } curl_multi_close($mh);$mh=NULL;$conn=NULL;$connomains=NULL; return $res; }//cmi

     


    最新回复(0)