批量下载文件一般使用循环的方式,逐一执行下载。但在带宽与服务器性能允许的情况下,使用多进程进行下载可以大大提高下载的效率。本文介绍php利用curl的多进程请求方法,实现多进程同时下载文件。

原理:

使用curl的批处理方法,开启多进程,实现批量下载文件。

主要方法:

curl_multi_init

返回一个新cURL批处理句柄

curl_multi_add_handle

向curl批处理会话中添加单独的curl句柄

curl_multi_exec

运行当前 cURL 句柄的子连接

curl_multi_getcontent

如果设置了CURLOPT_RETURNTRANSFER,则返回获取的输出的文本流

curl_multi_remove_handle

移除curl批处理句柄资源中的某个句柄资源

curl_multi_close

关闭一组cURL句柄

完整代码如下:

BatchDownLoad.class.php<?php /**

* 多进程批量下载文件(使用php curl_multi_exec实现)

* Date: 2017-07-16

* Author: fdipzone

* Version: 1.0

*

* Func

* public download 下载处理

* public process 多进程下载

* private to_log 将执行结果写入日志文件

*/class BatchDownLoad {

// 下载文件设置

private $download_config = array(); // 最大开启进程数量

private $max_process_num = 10; // 超时秒数

private $timeout = 10; // 日志文件

private $logfile = null; /**

* 初始化

* @param Array $download_config 下载的文件设置

* @param Int $max_process_num 最大开启的进程数量

* @param Int $timeout 超时秒数

* @param String $logfile 日志文件路径

*/

public function __construct($download_config, $max_process_num=10, $timeout=10, $logfile=''){

$this->download_config = $download_config; $this->max_process_num = $max_process_num; $this->timeout = $timeout; // 日志文件

if($logfile){ $this->logfile = $logfile;

}else{ $this->logfile = dirname(__FILE__).'/batch_download_'.date('Ymd').'.log';

}

} /**

* 执行下载

* @result Int

*/

public function download(){

// 已处理的数量

$handle_num = 0; // 未处理完成

while(count($this->download_config)>0){ // 需要处理的大于最大进程数

if(count($this->download_config)>$this->max_process_num){ $process_num = $this->max_process_num; // 需要处理的小于最大进程数

}else{ $process_num = count($this->download_config);

} // 抽取指定数量进行下载

$tmp_download_config = array_splice($this->download_config, 0, $process_num); // 执行下载

$result = $this->process($tmp_download_config); // 写入日志

$this->to_log($tmp_download_config, $result); // 记录已处理的数量

$handle_num += count($result);

} return $handle_num;

} /**

* 多进程下载文件

* @param Array $download_config 本次下载的设置

* @return Array

*/

public function process($download_config){

// 文件资源

$fp = array(); // curl会话

$ch = array(); // 执行结果

$result = array(); // 创建curl handle

$mh = curl_multi_init(); // 循环设定数量

foreach($download_config as $k=>$config){ $ch[$k] = curl_init(); $fp[$k] = fopen($config[1], 'a');

curl_setopt($ch[$k], CURLOPT_URL, $config[0]);

curl_setopt($ch[$k], CURLOPT_FILE, $fp[$k]);

curl_setopt($ch[$k], CURLOPT_HEADER, 0);

curl_setopt($ch[$k], CURLOPT_RETURNTRANSFER, true);

curl_setopt($ch[$k], CURLOPT_USERAGENT, 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)'); // 加入处理

curl_multi_add_handle($mh, $ch[$k]);

} $active = null; do{ $mrc = curl_multi_exec($mh, $active);

} while($active); // 获取数据

foreach($fp as $k=>$v){

fwrite($v, curl_multi_getcontent($ch[$k]));

} // 关闭curl handle与文件资源

foreach($download_config as $k=>$config){

curl_multi_remove_handle($mh, $ch[$k]);

fclose($fp[$k]); // 检查是否下载成功

if(file_exists($config[1])){ $result[$k] = true;

}else{ $result[$k] = false;

}

}

curl_multi_close($mh); return $result;

} /**

* 写入日志

* @param Array $data 下载文件数据

* @param Array $flag 下载文件状态数据

*/

private function to_log($data, $flag){

// 临时日志数据

$tmp_log = ''; foreach($data as $k=>$v){ $tmp_log .= '['.date('Y-m-d H:i:s').'] url:'.$v[0].' file:'.$v[1].' status:'.$flag[$k].PHP_EOL;

} // 创建日志目录

if(!is_dir(dirname($this->logfile))){

mkdir(dirname($this->logfile), 0777, true);

} // 写入日志文件

file_put_contents($this->logfile, $tmp_log, FILE_APPEND);

}

}?>

demo.php<?phprequire 'BatchDownLoad.class.php';$base_path = dirname(__FILE__).'/photo';$download_config = array( array('http://www.example.com/p1.jpg', $base_path.'/p1.jpg'), array('http://www.example.com/p2.jpg', $base_path.'/p2.jpg'), array('http://www.example.com/p3.jpg', $base_path.'/p3.jpg'), array('http://www.example.com/p4.jpg', $base_path.'/p4.jpg'), array('http://www.example.com/p5.jpg', $base_path.'/p5.jpg'),

);$obj = new BatchDownLoad($download_config, 2, 10);$handle_num = $obj->download();echo 'download num:'.$handle_num.PHP_EOL;?>

执行后日志输出[2017-07-16 18:04:21] url:http://www.example.com/p1.jpg file:/home/fdipzone/photo/p1.jpg status:1[2017-07-16 18:04:21] url:http://www.example.com/p2.jpg file:/home/fdipzone/photo/p2.jpg status:1[2017-07-16 18:04:21] url:http://www.example.com/p3.jpg file:/home/fdipzone/photo/p3.jpg status:1[2017-07-16 18:04:21] url:http://www.example.com/p4.jpg file:/home/fdipzone/photo/p4.jpg status:1[2017-07-16 18:04:21] url:http://www.example.com/p5.jpg file:/home/fdipzone/photo/p5.jpg status:1

本篇文章讲解了批量下载文件的一些方式,更多相关内容请关注php中文网。

相关推荐:关于php 日志类的讲解

php 实现curl下载,如何利用phpcurl实现多进程下载文件类相关推荐

  1. 利用AVR单片机 专用下载 USBtinyISP对Arduino UNO下载程序

    简 介: 测试了利用USBtinyISP对于Arduino UNO,也就是ATmega系列的单片机下载Bootloader的过程.通过测试可以看到,利用USBtinyISP可以更快的下载ATmega系 ...

  2. QT学习笔记(-): 利用QHttp进行http下载(1)

    利用 Qhttp 实现http下载 今天学习了一下Qt的http下载(当然,利用http也可以实现上传), 利用的是QHttp这个类来实现, 实现方式比较简单, 下面给出实现方法供大家参考. 我们新建 ...

  3. Springboot利用poi导出excel下载

    Springboot利用poi导出excel下载 因为项目中之前的做法是用反射获取属性,所以demo中也是用的反射,我看网上很多文章都是存入一个List中,不知道这两种哪种更何合适一点,或者有什么更好 ...

  4. 战网下载CDN重定向失败_卧槽,又开源一个下载神器,利用各种平台下载任意文件...

    @Travis-CI && @GithubAction && @Coding && @Vercel,你帮我下载文件行吗QvQ 前言 开源地址:https ...

  5. 利用ffmpeg将m3u8下载成mp4(利用ps1脚本解析json批量下载)

    利用ffmpeg将m3u8下载成mp4 安装ffmpeg JSON文件示例(自行抓取m3u8) powershell脚本 打开powershell运行 安装ffmpeg 自行baidu JSON文件示 ...

  6. 利用python you-get库下载网络视频、音乐及图片

    Python,让繁琐工作高效便捷:利用python you-get库单个.批量下载网络视频.音乐及图片,you-get命令需要在cmd窗口中运行. 很多人学习python,不知道从何学起. 很多人学习 ...

  7. 利用多线程实现的下载器,完爆迅雷!

    原文:利用多线程实现的下载器,完爆迅雷! 源代码下载地址:http://www.zuidaima.com/share/1550463611374592.htm 方便,快捷~~~程序猿必备利器 界面是用 ...

  8. 利用Chrome浏览器“自动下载”功能窃取Windows登录密码

    本文讲的是利用Chrome浏览器"自动下载"功能窃取Windows登录密码,在过去的十几年中,除了IE以及Edge浏览器之外,其余还没有公开针对SMB认证攻击的方法.这篇文章介绍的 ...

  9. 利用IO流一次性读取文件中的所有内容,利用IO流下载文件

    利用IO流一次性读取文件中的所有内容 读取文件效率最快的方法就是一次全读进来,使用readline()之类的方法,可能需要反复访问文件,而且每次readline()都会调用编码转换,降低了速度,所以, ...

最新文章

  1. 高内聚、低耦合的含义是什么?
  2. 约数个数shlqsh
  3. sed行文本处理工具
  4. c语言头文件格式图片_c语言中的.h头文件的格式
  5. 技术公开课:SQL Server 索引优化原则与工具
  6. iOS IM开发建议(一)App框架设计
  7. 判断文件格式并输出文件流
  8. 第九章(三)多阶段决策问题
  9. 802.1X体系介绍
  10. 微软开放必应搜索引擎核心算法
  11. ps排版html,排版教程,超详细适合初学者的排版教程
  12. 【计算理论】计算复杂性 ( NP 完全问题 | NP 难 问题 P = NP 的情况 | NP 难 问题 P ≠ NP 的情况 )
  13. Windows XP和Windows 7双系统安装说明和注意事项
  14. 深度测评 | 五大主流多端开发框架全面对比
  15. python pyplot bar 参数_数据可视化之条形图(1):Axes.bar
  16. 2021-CISCN-fianl-ezj4va
  17. Oracle Forensics t00ls
  18. 网络平台做用户实名认证的好处
  19. html dw map,DW制作地图之map标签
  20. HDU-6555 The Fool

热门文章

  1. html在线图片编辑器,超好用的html在线编辑器
  2. 315MHZ PT2272-M4 非锁四路无线遥控 发射接收方案
  3. 电脑录音软件哪个好用?如何录制声音?
  4. ant--Java工程打包工具
  5. 惊天阴谋-陈晓如何窃取国美电器的
  6. 国美公告暂停黄光裕及其妻杜鹃职务
  7. NS中如何编制带有期初/发生/期末余额的资产负债表?
  8. 计算机应届博士生的一点求职经验——字节篇
  9. 迅雷校招产品经理面试
  10. MySQL无法成功启动