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 相关文章推荐
Win2000+Apache+MySql+PHP4+PERL安装使用小结
Oct 09 PHP
php中的注释、变量、数组、常量、函数应用介绍
Nov 16 PHP
Window下PHP三种运行方式图文详解
Jun 11 PHP
php读取二进制流(C语言结构体struct数据文件)的深入解析
Jun 13 PHP
PHP高级编程实例:编写守护进程
Sep 02 PHP
如何使用php实现评委评分器
Jul 31 PHP
php 利用array_slice函数获取随机数组或前几条数据
Sep 30 PHP
在PHP中使用FastCGI解析漏洞及修复方案
Nov 10 PHP
PHP利用imagick生成组合缩略图
Feb 19 PHP
浅谈PHP正则中的捕获组与非捕获组
Jul 18 PHP
PHP分享图片的生成方法
Apr 25 PHP
Laravel框架使用Seeder实现自动填充数据功能
Jun 13 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 calender(日历)二个版本代码示例(解决2038问题)
2013/12/24 PHP
PHP小教程之实现双向链表
2014/06/12 PHP
php 计算两个时间相差的天数、小时数、分钟数、秒数详解及实例代码
2016/11/09 PHP
JavaScript 题型问答有答案参考
2010/02/17 Javascript
!DOCTYPE声明对JavaScript的影响分析
2010/04/12 Javascript
jquery关于图形报表的运用实现代码
2011/01/06 Javascript
jQuery判断元素是否是隐藏的代码
2011/04/24 Javascript
基于jquery的弹出提示框始终处于窗口的居中位置(类似于alert弹出框的效果)
2011/09/28 Javascript
深入理解JavaScript系列(7) S.O.L.I.D五大原则之开闭原则OCP
2012/01/15 Javascript
IE浏览器下PNG相关功能
2015/07/05 Javascript
JavaScritp添加url参数并将参数加入到url中及更改url参数的方法
2015/10/26 Javascript
javascript动画之磁性吸附效果篇
2016/12/09 Javascript
如何写好你的JavaScript【推荐】
2017/03/02 Javascript
详解vue.js 开发环境搭建最简单攻略
2017/06/12 Javascript
JS二分查找算法详解
2017/11/01 Javascript
vue 本地环境跨域请求proxyTable的方法
2018/09/19 Javascript
Node.js如何对SQLite的async/await封装详解
2019/02/14 Javascript
使用Vue生成动态表单
2019/11/26 Javascript
jquery传参及获取方式(两种方式)
2020/02/13 jQuery
[07:48]DOTA2上海特级锦标赛主赛事首日RECAP
2016/03/04 DOTA
[00:09]DOTA2全国高校联赛 精彩活动引爆全场
2018/05/30 DOTA
[01:05:56]Liquid vs VP Supermajor决赛 BO 第二场 6.10
2018/07/04 DOTA
Windows下的Python 3.6.1的下载与安装图文详解(适合32位和64位)
2018/02/21 Python
怎么使用pipenv管理你的python项目
2018/03/12 Python
基于python cut和qcut的用法及区别详解
2019/11/22 Python
python每5分钟从kafka中提取数据的例子
2019/12/23 Python
Python计算IV值的示例讲解
2020/02/28 Python
python使用建议与技巧分享(二)
2020/08/17 Python
python 浮点数四舍五入需要注意的地方
2020/08/18 Python
美国生鲜及杂货电商:FreshDirect
2018/01/29 全球购物
企业管理培训感言
2014/01/27 职场文书
处级领导干部四风问题自我剖析材料
2014/09/29 职场文书
党委班子纠正“四风”问题整改措施
2014/10/28 职场文书
工作失职自我检讨书
2015/05/05 职场文书
2015年学校综合治理工作总结
2015/07/20 职场文书
JavaWeb 入门篇(3)ServletContext 详解 具体应用
2021/07/16 Java/Android