详解PHP中curl_multi并发的实现


Posted in PHP onJune 08, 2020

PHP中的curl_multi系列函数可以实现同时请求多个URL来实现并发,而不是像普通curl函数那样请求后会阻塞,直到结果返回才进行下一个请求。因此在批量请求URL时可通过curl_multi系列函数提升程序的运行效率。

curl普通请求

$startTime = microtime(true);
$chArr = [];
$optArr = [
  CURLOPT_URL => 'http://www.httpbin.org/ip',
  CURLOPT_HEADER => 0,
  CURLOPT_RETURNTRANSFER => 1,
];
$result = [];

//创建多个curl资源并执行
for ($i=0; $i<10; $i++) {
  $chArr[$i] = curl_init();
  curl_setopt_array($chArr[$i], $optArr);
  $result[$i] = curl_exec($chArr[$i]);
  curl_close($chArr[$i]);
}

$endTime = microtime(true);
echo sprintf("use time: %.3f s".PHP_EOL, $endTime - $startTime);

use time: 6.080 s

curl_multi并发请求

$startTime = microtime(true);
$chArr = [];
$optArr = [
  CURLOPT_URL => 'http://www.httpbin.org/ip',
  CURLOPT_HEADER => 0,
  CURLOPT_RETURNTRANSFER => 1,
];
$result = [];

//创建多个curl资源
for ($i=0; $i<10; $i++) {
  $chArr[$i] = curl_init();
  curl_setopt_array($chArr[$i], $optArr);
}
//创建批处理curl句柄
$mh = curl_multi_init();
//将单个curl句柄添加到批处理curl句柄中
foreach ($chArr as $ch) {
  curl_multi_add_handle($mh, $ch);
}
//判断操作是否仍在执行的标识的引用
$active = null;
/**
 * 本次循环第一次处理 $mh 批处理中的 $ch 句柄,并将 $mh 批处理的执行状态写入 $active,
 * 当状态值等于 CURLM_CALL_MULTI_PERFORM 时,表明数据还在写入或读取中,执行循环,
 * 当第一次 $ch 句柄的数据写入或读取成功后,状态值变为 CURLM_OK ,跳出本次循环,进入下面的大循环中。
 */
do {
  //处理在批处理栈中的每一个句柄
  $mrc = curl_multi_exec($mh, $active);
} while ($mrc == CURLM_CALL_MULTI_PERFORM);
/**
 * 上面这段代码中,是可以直接使用 $active > 0 来作为 while 的条件,如下:
 * do {
 *  $mrc = curl_multi_exec($mh, $active);
 * } while ($active > 0);
 * 此时如果整个批处理句柄没有全部执行完毕时,系统会不停的执行 curl_multi_exec 函数,从而导致系统CPU占用会很高,
 * 因此一般不采用这种方案,可以通过 curl_multi_select 函数来达到没有需要读取的程序就阻塞住的目的。
 */

/**
 * $active 为 true 时,即 $mh 批处理之中还有 $ch 句柄等待处理,
 * $mrc == CURLM_OK,即上一次 $ch 句柄的读取或写入已经执行完毕。
 */
while ($active && $mrc == CURLM_OK) {
  /** 
   * 程序进入阻塞状态,直到批处理中有活动连接(即 $mh 批处理中还有可执行的 $ch 句柄),
   * 这样执行的好处是 $mh 批处理中的 $ch 句柄会在读取或写入数据结束后($mrc == CURLM_OK)进入阻塞阶段,
   * 而不会在整个 $mh 批处理执行时不停地执行 curl_multi_exec 函数,白白浪费CPU资源。
   */
   if (curl_multi_select($mh) != -1) {
    //程序退出阻塞状态继续执行需要处理的 $ch 句柄
    do {
      $mrc = curl_multi_exec($mh, $active);
    } while ($mrc == CURLM_CALL_MULTI_PERFORM);
  }
}

foreach ($chArr as $i=>$ch) {
  //获取某个curl句柄的返回值
  $result[$i] = curl_multi_getcontent($ch);
  //移除批处理句柄中的某个句柄资源
  curl_multi_remove_handle($mh, $ch);
}
//关闭一组curl句柄
curl_multi_close($mh);
$endTime = microtime(true);
echo sprintf("use time: %.3f s".PHP_EOL, $endTime - $startTime);

use time: 0.599 s

通过对比上述程序的运行时间可以得知,使用curl_multi系列函数并发请求要比普通的curl函数依次请求效率高很多。

到此这篇关于详解PHP中curl_multi并发的实现的文章就介绍到这了,更多相关PHP curl_multi并发内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木! 

PHP 相关文章推荐
利用 window_onload 实现select默认选择
Oct 09 PHP
落伍首发 php+mysql 采用ajax技术的 省 市 地 3级联动无刷新菜单 源码
Dec 16 PHP
PHP下利用header()函数设置浏览器缓存的代码
Sep 01 PHP
php生成略缩图代码
Jul 16 PHP
解析php中两种缩放图片的函数,为图片添加水印
Jun 14 PHP
php+ajax实现的点击浏览量加1
Apr 16 PHP
PHP多态代码实例
Jun 26 PHP
php版微信公众平台接口参数调试实现判断用户行为的方法
Sep 23 PHP
thinkphp3.2中实现phpexcel导出带生成图片示例
Feb 14 PHP
详解php中serialize()和unserialize()函数
Jul 08 PHP
thinkphp5框架实现的自定义扩展类操作示例
May 16 PHP
PHP 出现 http500 错误的解决方法
Mar 09 PHP
THINKPHP5.1 Config的配置与获取详解
Jun 08 #PHP
ThinkPHP5.1验证码功能实现的示例代码
Jun 08 #PHP
php框架CI(codeigniter)自动加载与自主创建对象操作实例分析
Jun 06 #PHP
CI框架简单分页类用法示例
Jun 06 #PHP
简单的php购物车代码
Jun 05 #PHP
实例化php类时传参的方法分析
Jun 05 #PHP
PHP页面静态化――纯静态与伪静态用法详解
Jun 05 #PHP
You might like
新版PHP极大的增强功能和性能
2006/10/09 PHP
php的mail函数发送UTF-8编码中文邮件时标题乱码的解决办法
2015/10/20 PHP
CI框架入门之MVC简单示例
2016/11/21 PHP
php版阿里云OSS图片上传类详解
2016/12/01 PHP
PHP实现表单提交数据的验证处理功能【防SQL注入和XSS攻击等】
2017/07/21 PHP
JavaScript中数组的排序、乱序和搜索实现代码
2011/11/30 Javascript
js获取控件位置以及不同浏览器中的差别介绍
2013/08/08 Javascript
JS预览图像将本地图片显示到浏览器上
2013/08/25 Javascript
jquery实现加载等待效果示例
2013/09/25 Javascript
使用js画图之饼图
2015/01/12 Javascript
Javascript 是你的高阶函数(高级应用)
2015/06/15 Javascript
jQuery实现的placeholder效果完整实例
2016/08/02 Javascript
深入理解JS DOM事件机制
2016/08/06 Javascript
AngularJS中的缓存使用
2017/01/11 Javascript
基于JavaScript实现屏幕滚动效果
2017/01/18 Javascript
vue页面切换过渡transition效果
2018/10/08 Javascript
angularjs模态框的使用代码实例
2019/12/20 Javascript
[02:49]2018DOTA2亚洲邀请赛主赛事决赛日战况回顾 Mineski鏖战5局夺得辉耀
2018/04/10 DOTA
Python读取图片EXIF信息类库介绍和使用实例
2014/07/10 Python
Nginx搭建HTTPS服务器和强制使用HTTPS访问的方法
2015/08/16 Python
用Python一键搭建Http服务器的方法
2018/06/01 Python
Python爬虫爬取新浪微博内容示例【基于代理IP】
2018/08/03 Python
python生成lmdb格式的文件实例
2018/11/08 Python
Python爬取爱奇艺电影信息代码实例
2019/11/26 Python
解决在keras中使用model.save()函数保存模型失败的问题
2020/05/21 Python
Python 实现国产SM3加密算法的示例代码
2020/09/21 Python
css3中单位px,em,rem,vh,vw,vmin,vmax的区别及浏览器支持情况
2016/12/06 HTML / CSS
canvas实现扭蛋机动画效果的示例代码
2018/10/17 HTML / CSS
HTML5自定义属性的问题分析
2019/08/16 HTML / CSS
美国女性服饰销售网站:Nasty Gal(坏女孩)
2016/07/26 全球购物
限量版运动鞋和街头服饰:TheDrop
2020/09/06 全球购物
写给女朋友的道歉信
2014/01/08 职场文书
文明生主要事迹
2014/05/25 职场文书
个人党性分析总结
2015/03/05 职场文书
2015国庆节感想
2015/08/04 职场文书
信息技术研修心得体会
2016/01/08 职场文书