详解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 相关文章推荐
一个用于mysql的数据库抽象层函数库
Oct 09 PHP
一个ubbcode的函数,速度很快.
Oct 09 PHP
php日历制作代码分享
Jan 20 PHP
yii框架builder、update、delete使用方法
Apr 30 PHP
PHP中使用hidef扩展代替define提高性能
Apr 09 PHP
php 利用array_slice函数获取随机数组或前几条数据
Sep 30 PHP
修复ShopNC使用QQ 互联时提示100010 错误
Nov 08 PHP
利用PHP将图片转换成base64编码的实现方法
Sep 13 PHP
ZendFramework2连接数据库操作实例
Apr 18 PHP
PHP学习记录之数组函数
Jun 01 PHP
PHP利用pdo_odbc实现连接数据库示例【基于ThinkPHP5.1搭建的项目】
May 13 PHP
PHP实现财务审核通过后返现金额到客户的功能
Jul 04 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 csv操作类代码
2009/12/14 PHP
深入解析php之sphinx
2013/05/15 PHP
Yii2使用小技巧之通过 Composer 添加 FontAwesome 字体资源
2014/06/22 PHP
PHP制作图形验证码代码分享
2014/10/23 PHP
PDO防注入原理分析以及使用PDO的注意事项总结
2014/10/23 PHP
PHP获取ip对应地区和使用网络类型的方法
2015/03/11 PHP
PHP SPL标准库之文件操作(SplFileInfo和SplFileObject)实例
2015/05/11 PHP
php 使用html5实现多文件上传实例
2016/10/24 PHP
php常用经典函数集锦【数组、字符串、栈、队列、排序等】
2019/08/23 PHP
JavaScript中令你抓狂的魔术变量
2006/11/30 Javascript
js实现的map方法示例代码
2014/01/13 Javascript
Js判断CSS文件加载完毕的具体实现
2014/01/17 Javascript
js 与 php 通过json数据进行通讯示例
2014/03/26 Javascript
JS仿iGoogle自定义首页模块拖拽特效的方法
2015/02/13 Javascript
深入理解JavaScript系列(49):Function模式(上篇)
2015/03/04 Javascript
jQuery+css3实现文字跟随鼠标的上下抖动
2015/07/31 Javascript
JS实现的表格操作类详解(添加,删除,排序,上移,下移)
2015/12/22 Javascript
JavaScript遍历Json串浏览器输出的结果不统一问题
2016/11/03 Javascript
jquery动态赋值id与动态取id方法示例
2017/08/21 jQuery
jQuery实现上下滚动公告栏详细代码
2018/11/21 jQuery
基于vue的验证码组件的示例代码
2019/01/22 Javascript
详解vue2.0模拟后台json数据
2019/05/16 Javascript
python利用正则表达式搜索单词示例代码
2017/09/24 Python
Python自定义简单图轴简单实例
2018/01/08 Python
python的移位操作实现详解
2019/08/21 Python
tensorflow 实现从checkpoint中获取graph信息
2020/02/10 Python
Python with语句用法原理详解
2020/07/03 Python
幼师岗位求职简历的自荐信格式
2013/09/21 职场文书
高三自我鉴定范文
2013/10/19 职场文书
个人自我鉴定怎么写
2013/10/28 职场文书
质量管理标语
2014/06/12 职场文书
考试保密承诺书
2014/08/30 职场文书
拾金不昧感谢信
2015/01/21 职场文书
项目负责人岗位职责
2015/02/15 职场文书
2016年艾滋病宣传活动总结
2016/04/01 职场文书
MongoDB数据库之添删改查
2022/04/26 MongoDB