php curl高并发_PHP CURL 实现并发访问网络资源

PHP cURL 所有函数列表:

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

/*

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时就是并发执行请求了(可以用于计划任务)

//后面的几个参数的详细说明请看注释,毕竟函数不长

*/

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('/[\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;

/*

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时就是并发执行请求了(可以用于计划任务)

//后面的几个参数的详细说明请看注释,毕竟函数不长

*/

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('/[\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;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值