php中的curl_multi系列函数使用例子


Posted in PHP onJuly 29, 2014

相信许多人对php手册中语焉不详的curl_multi一族的函数头疼不已,它们文档少,给的例子 更是简单的让你无从借鉴,我也曾经找了许多网页,都没见一个完整的应用例子。

  • curl_multi_add_handle
  • curl_multi_close
  • curl_multi_exec
  • curl_multi_getcontent
  • curl_multi_info_read
  • curl_multi_init
  • curl_multi_remove_handle
  • curl_multi_select

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

步骤总结如下:

第一步:调用curl_multi_init
第二步:循环调用curl_multi_add_handle
这一步需要注意的是,curl_multi_add_handle的第二个参数是由curl_init而来的子handle。
第三步:持续调用curl_multi_exec
第四步:根据需要循环调用curl_multi_getcontent获取结果
第五步:调用curl_multi_remove_handle,并为每个字handle调用curl_close
第六步:调用curl_multi_close

这里有一个网上找的简单例子,其作者称为dirty的例子,(稍后我会说明为何dirty):

/*

Here's a quick and dirty example for curl-multi from PHP, tested on PHP 5.0.0RC1 CLI / FreeBSD 5.2.1

*/
$connomains = array(

"http://www.baidu.com/",

"http://www.google.com/",

"https://3water.com/"

);

$mh = curl_multi_init();
foreach ($connomains as $i => $url) {

     $conn[$i]=curl_init($url);

      curl_setopt($conn[$i],CURLOPT_RETURNTRANSFER,1);

      curl_multi_add_handle ($mh,$conn[$i]);

}
do { $n=curl_multi_exec($mh,$active); } while ($active);
foreach ($connomains as $i => $url) {

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

      curl_close($conn[$i]);

}
print_r($res);

整个使用过程差不多就是这样,但是,这个简单代码有个致命弱点,就是在do循环的那段,在整个url请求期间是个死循环,它会轻易导致CPU占用100%。

现在我们来改进它,这里要用到一个几乎没有任何文档的函数curl_multi_select了,虽然C的curl库对select有说明,但是,php里的接口和用法确与C中有不同。

把上面do的那段改成下面这样:

           do {

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

                } while ($mrc == CURLM_CALL_MULTI_PERFORM);

                while ($active and $mrc == CURLM_OK) {

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

                                do {

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

                                } while ($mrc == CURLM_CALL_MULTI_PERFORM);

                        }

                }

因为$active要等全部url数据接受完毕才变成false,所以这里用到了curl_multi_exec的返回值判断是否还有数据,当有数据的时候就不停调用curl_multi_exec,暂时没有数据就进入select阶段,新数据一来就可以被唤醒继续执行。这里的好处就是CPU的无谓消耗没有了。

另外:还有一些细节的地方可能有时候要遇到:

控制每一个请求的超时时间,在curl_multi_add_handle之前通过curl_setopt去做:

curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);

判断是否超时了或者其他错误,在curl_multi_getcontent之前用:curl_error($conn[$i]);

PHP 相关文章推荐
使用 MySQL Date/Time 类型
Mar 26 PHP
Ajax+PHP 边学边练之四 表单
Nov 27 PHP
PHP高自定义性安全验证码代码
Nov 27 PHP
在项目中寻找代码的坏命名
Jul 14 PHP
PHP以指定字段为索引返回数据库所取的数据数组
Jun 30 PHP
PHP输出英文时间日期的安全方法(RFC 1123格式)
Jun 13 PHP
百度工程师讲PHP函数的实现原理及性能分析(一)
May 13 PHP
PHP实现冒泡排序的简单实例
May 26 PHP
PHP中FTP相关函数小结
Jul 15 PHP
Thinkphp实现短信验证注册功能
Oct 18 PHP
深入浅出讲解:php的socket通信原理
Dec 03 PHP
Yii redis集合的基本使用教程
Jun 14 PHP
PHP使用CURL_MULTI实现多线程采集的例子
Jul 29 #PHP
PHP实现把文本中的URL转换为链接的auolink()函数分享
Jul 29 #PHP
PHP自带函数给数字或字符串自动补齐位数
Jul 29 #PHP
Win2003+apache+PHP+SqlServer2008 配置生产环境
Jul 29 #PHP
php实现读取超大文件的方法
Jul 28 #PHP
将CMYK颜色值和RGB颜色相互转换的PHP代码
Jul 28 #PHP
php Imagick获取图片RGB颜色值
Jul 28 #PHP
You might like
php不允许用户提交空表单(php空值判断)
2013/11/12 PHP
destoon实现调用热门关键字的方法
2014/07/15 PHP
PHP实现获取域名的方法小结
2014/11/05 PHP
php生成PDF格式文件并且加密
2015/06/22 PHP
文件上传之SWFUpload插件(代码)
2015/07/30 PHP
自制PHP框架之模型与数据库
2017/05/07 PHP
PHP中十六进制颜色与RGB颜色值互转的方法
2019/03/18 PHP
laravel 实现用户登录注销并限制功能
2019/10/24 PHP
JavaScript之appendChild、insertBefore和insertAfter使用说明
2010/12/30 Javascript
javascript数组去重3种方法的性能测试与比较
2013/03/26 Javascript
javascript读取xml实现javascript分页
2013/12/13 Javascript
Javascript 按位与运算符 (&)使用介绍
2014/02/04 Javascript
IE6-IE9使用JSON、table.innerHTML所引发的问题
2015/12/22 Javascript
jQuery中inArray方法注意事项分析
2016/01/25 Javascript
JS添加或修改控件的样式(Class)实现方法
2016/10/15 Javascript
js调用父框架函数与弹窗调用父页面函数的简单方法
2016/11/01 Javascript
jQuery EasyUI中的日期控件DateBox修改方法
2016/11/09 Javascript
JS多文件上传的实例代码
2017/01/11 Javascript
基于vue2.0+vuex+localStorage开发的本地记事本示例
2017/02/28 Javascript
基于node.js制作简单爬虫教程
2017/06/29 Javascript
Postman的下载及安装教程详解
2018/10/16 Javascript
js闭包的9个使用场景
2020/12/29 Javascript
python中的内置函数getattr()介绍及示例
2014/07/20 Python
对python中Matplotlib的坐标轴的坐标区间的设定实例讲解
2018/05/25 Python
Python3模拟登录操作实例分析
2019/03/12 Python
Python3 JSON编码解码方法详解
2019/09/06 Python
图解python全局变量与局部变量相关知识
2019/11/02 Python
tensorflow 自定义损失函数示例代码
2020/02/05 Python
Python爬虫小例子——爬取51job发布的工作职位
2020/07/10 Python
通过实例解析python subprocess模块原理及用法
2020/10/10 Python
Python通过字典映射函数实现switch
2020/11/06 Python
如何设置PyCharm中的Python代码模版(推荐)
2020/11/20 Python
行政助理岗位职责范文
2013/12/03 职场文书
三下乡活动方案
2014/01/31 职场文书
餐厅总厨求职信
2014/03/04 职场文书
《忆江南》教学反思
2014/04/07 职场文书