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 相关文章推荐
用php+javascript实现二级级联菜单的制作
May 06 PHP
php error_log 函数的使用
Apr 13 PHP
PHP面向对象概念
Nov 06 PHP
PHP中的错误处理、异常处理机制分析
May 07 PHP
thinkphp实现图片上传功能分享
Mar 04 PHP
php获取客户端电脑屏幕参数的方法
Jan 09 PHP
golang与php实现计算两个经纬度之间距离的方法
Jul 22 PHP
php+redis实现商城秒杀功能
Nov 19 PHP
php处理抢购类功能的高并发请求
Feb 08 PHP
PHP共享内存使用与信号控制实例分析
May 09 PHP
Windows下wamp php单元测试工具PHPUnit安装及生成日志文件配置方法
May 28 PHP
使用Rancher在K8S上部署高性能PHP应用程序的教程
Jul 10 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 selectradio和checkbox默认选择的实现方法详解
2013/06/29 PHP
微信公众平台网页授权获取用户基本信息中授权回调域名设置的变动
2014/10/21 PHP
PHP与Web页面的交互示例详解二
2020/08/04 PHP
JS 控制CSS样式表
2009/08/20 Javascript
Javascript 面向对象 命名空间
2010/05/13 Javascript
可以用鼠标拖动的DIV实现思路及代码
2013/10/21 Javascript
阻止事件(取消浏览器对事件的默认行为并阻止其传播)
2013/11/03 Javascript
JavaScript中setTimeout和setInterval函数的传参及调用
2016/03/11 Javascript
JS数组操作之增删改查的简单实现
2017/08/21 Javascript
基于node.js之调试器详解
2017/08/22 Javascript
vue axios请求频繁时取消上一次请求的方法
2018/11/10 Javascript
angular6开发steps步骤条组件
2019/07/04 Javascript
解决vue-photo-preview 异步图片放大失效的问题
2020/07/29 Javascript
Angular+Ionic使用queryParams实现跳转页传值的方法
2020/09/05 Javascript
Python实现二维有序数组查找的方法
2016/04/27 Python
django反向解析和正向解析的方式
2018/06/05 Python
Python3实现爬虫爬取赶集网列表功能【基于request和BeautifulSoup模块】
2018/12/05 Python
matplotlib.pyplot绘图显示控制方法
2019/01/15 Python
Python获取一个用户名的组ID过程解析
2019/09/03 Python
Python基于stuck实现scoket文件传输
2020/04/02 Python
Pytorch上下采样函数--interpolate用法
2020/07/07 Python
python遍历路径破解表单的示例
2020/11/21 Python
美国体育用品商店:Rally House(NCAA、NFL、MLB、NBA、NHL和MLS)
2018/01/03 全球购物
英国家用电器折扣网站:Electrical Discount UK
2018/09/17 全球购物
创建精神文明单位实施方案
2014/03/08 职场文书
助人为乐模范事迹材料
2014/06/02 职场文书
分公司总经理岗位职责
2014/07/30 职场文书
活动总结新闻稿
2014/08/30 职场文书
新教师培训心得体会
2014/09/02 职场文书
上党课的心得体会
2014/09/02 职场文书
假释思想汇报范文
2014/10/11 职场文书
解除施工合同协议书
2014/10/17 职场文书
生产车间主任岗位职责
2015/04/08 职场文书
PHP实现创建以太坊钱包转账等功能
2021/04/21 PHP
浅谈golang package中init方法的多处定义及运行顺序问题
2021/05/06 Golang
如何用PHP实现多线程编程
2021/05/26 PHP