详解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 相关文章推荐
PHP简单系统数据添加以及数据删除模块源文件下载
Jun 07 PHP
php相当简单的分页类
Oct 02 PHP
php数据库密码的找回的步骤
Jan 12 PHP
php学习笔记(三)操作符与控制结构
Aug 06 PHP
供参考的 php 学习提高路线分享
Oct 23 PHP
php根据分类合并数组的方法实例详解
Nov 06 PHP
php写的AES加密解密类分享
Jun 20 PHP
PHP速成大法
Jan 30 PHP
PHP字符串逆序排列实现方法小结【strrev函数,二分法,循环法,递归法】
Jan 13 PHP
PHP基于curl post实现发送url及相关中文乱码问题解决方法
Nov 25 PHP
PHP的PDO错误与错误处理
Jan 27 PHP
Laravel框架下的Contracts契约详解
Mar 17 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
欧美媒体选出10年前最流行的17部动画
2017/01/18 日漫
php项目打包方法
2008/02/18 PHP
php之Memcache学习笔记
2013/06/17 PHP
Yii2使用dropdownlist实现地区三级联动功能的方法
2016/07/18 PHP
Laravel 关联模型-关联新增和关联更新的方法
2019/10/10 PHP
PHP之header函数详解
2021/03/02 PHP
addEventListener和attachEvent二者绑定的执行函数中的this不相同
2012/12/09 Javascript
angularJS 中$scope方法使用指南
2015/02/09 Javascript
js全选实现和判断是否有复选框选中的方法
2015/02/17 Javascript
javascript判断css3动画结束 css3动画结束的回调函数
2015/03/10 Javascript
PHP+mysql+Highcharts生成饼状图
2015/05/04 Javascript
实例讲解jquery中mouseleave和mouseout的区别
2016/02/17 Javascript
JS定义类的六种方式详解
2016/05/12 Javascript
浅谈Node Inspector 代理实现
2017/10/19 Javascript
微信小程序中显示倒计时代码实例
2019/05/09 Javascript
python将字典内容存入mysql实例代码
2018/01/18 Python
python selenium自动上传有赞单号的操作方法
2018/07/05 Python
python3中函数参数的四种简单用法
2018/07/09 Python
Python字符串的全排列算法实例详解
2019/01/07 Python
Python 中的参数传递、返回值、浅拷贝、深拷贝
2019/06/25 Python
Python 中判断列表是否为空的方法
2019/11/24 Python
django中嵌套的try-except实例
2020/05/21 Python
python opencv图像处理(素描、怀旧、光照、流年、滤镜 原理及实现)
2020/12/10 Python
法国太阳镜店:Sunglasses Shop
2016/08/27 全球购物
欧洲最大的笔和书写专家:The Pen Shop
2017/03/19 全球购物
JBL英国官网:JBL UK
2018/07/04 全球购物
哪些情况下不应该使用索引
2015/07/20 面试题
金融专业大学生职业生涯规划范文
2014/01/16 职场文书
酒店总经理职务说明书
2014/02/26 职场文书
尊老爱亲美德少年事迹材料
2014/08/14 职场文书
自查自纠工作总结
2014/10/15 职场文书
2014年合同管理工作总结
2014/12/02 职场文书
2015年小学总务工作总结
2015/07/21 职场文书
预备党员的思想汇报,你真的会写吗?
2019/06/28 职场文书
七年级作文之冬景
2019/11/07 职场文书
HTML CSS 一个标签实现带动画的抖音LOGO
2022/04/26 HTML / CSS