php开启多线程下载

<pre>
<?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]);
}
//下面几句话就是执行多线程curl 不用理解为什么这样写 照着写就是了 如果执行好 $active会变成0的
$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);
}

}
date_default_timezone_set('Asia/Shanghai');
$base_path = dirname(__FILE__).'/phototest';

$download_config = array(
array('http://img.ads.csdn.net/2017/201707141625579530.jpg', $base_path.'/p1.jpg'),
array('http://geek.csdn.net/assets/images/geek_logo.png', $base_path.'/p2.jpg'),
array('http://images.csdn.net/20170718/Hans_meitu_401.jpg', $base_path.'/p3.jpg'),
);

$obj = new BatchDownLoad($download_config, 2, 10);
$handle_num = $obj->download();

echo 'download num:'.$handle_num.PHP_EOL;
?>

</pre>

ps:经过测试单线程和多线程下载速度是差不多的 因为带宽就这些 这是多线程能更好的使用带宽利用率

php开启多线程下载的更多相关文章

  1. Chrome开启多线程下载

    Chrome多线程下载也和标签页预览一样属于Google测试中的功能,可通过在地址栏输入chrome://flags/,然后在搜索框中输入Parallel downloading,选择enabled, ...

  2. 【Java EE 学习 22 下】【单线程下载】【单线程断点下载】【多线程下载】

    一.文件下载简述 1.使用浏览器从网页上下载文件,Servlet需要增加一些响应头信息 (1)response.setContentType("application/force-downl ...

  3. Java 仿迅雷多线程下载

    package net.webjoy.jackluo.android_json; /** * 1.http Range "bytes="+ start+end * 2.Random ...

  4. RandomAccessFile多线程下载、复制文件、超大文件读写

    最近在准备面试,翻了翻自己以前写的Demo,发现自己写了不少的工具包,今天整理了一下,分享给大家. 本文包含以下Demo: 1.常用方法测试 2.在文件中间插入一段新的数据 3.多线程下载文件 4.多 ...

  5. android程序---->android多线程下载(二)

    上篇我们讲到了android中下载的断点续传问题,今天我们开始学习下载的多线程问题.本次的多线程源码下载:androdi中多线程下载的实现代码.有关断点续传的问题,请参见博客:android程序--- ...

  6. android程序---->android多线程下载(一)

    多线程下载是加快下载速度的一种方式,通过开启多个线程去执行一个任务,可以使任务的执行速度变快.多线程的任务下载时常都会使用得到断点续传下载,就是我们在一次下载未结束时退出下载,第二次下载时会接着第一次 ...

  7. [C#]多线程下载

    发现电脑里以前编写的下载程序... 做个记录,那时做的挺匆忙的,没用委托,通过公开出窗体来修改下载进度,做的比较乱... ==!! 程序具体功能(流程): 1.检测系统托盘图标内的进程名是否符合要求 ...

  8. java多线程下载网络图片

    import java.io.BufferedInputStream;import java.io.BufferedOutputStream;import java.io.BufferedReader ...

  9. JAVA多线程下载网络文件

    JAVA多线程下载网络文件,开启多个线程,同时下载网络文件.   源码如下:(点击下载 MultiThreadDownload.java) import java.io.InputStream; im ...

随机推荐

  1. Greenplum 调优--数据倾斜排查(二)

    上次有个朋友咨询我一个GP数据倾斜的问题,他说查看gp_toolkit.gp_skew_coefficients表时花费了20-30分钟左右才出来结果,后来指导他分析原因并给出其他方案来查看数据倾斜. ...

  2. 剖析生产系统的I/O模式

    剖析生产系统的I/O模式 2019/02/13 vmunix 了解I/O的特点对于优化系统性能非常重要,I/O是顺序的还是随机的,是读操作还是写操作,读写的比例是多少,I/O数据块的大小,这些都是影响 ...

  3. java文件上传下载组件

    需求: 支持大文件批量上传(20G)和下载,同时需要保证上传期间用户电脑不出现卡死等体验: 内网百兆网络上传速度为12MB/S 服务器内存占用低 支持文件夹上传,文件夹中的文件数量达到1万个以上,且包 ...

  4. learning scala Function Recursive Tail Call

    可以使用scala库,可以从字面上看出是在调用 递归函数: code import scala.util.control.TailCalls._ val arrayDonuts: Array[Stri ...

  5. easy-table-vue+VueJs、SpringBoot+Mybatis实现MVVM模型前后台数据交互

    该项目分为前端展示部分和后台服务部分. 前端部分 使用的技术是:NodeJs.Webpack.VueJs 使用的组件库是:IVIEW.easy-table-vue 使用的开发工具是:WebStorm ...

  6. 利用 make_plan 规划起点到目标点的路径,并且发布出去

    geometry_msgs::PoseStamped Start; Start.header.seq = ; Start.header.stamp = Time(); Start.header.fra ...

  7. 研途APP——项目需求分析

    研途APP--项目需求分析 1.作业描述 项目 内容 课程 软件工程实践 作业链接 团队作业第二次-需求规格说明书 团队名称 8rookies 作业目标 作业正文 研途APP--项目需求分析 其他参考 ...

  8. 浅谈TextView Ellipsize效果与Marquee跑马灯无效果问题

    说到TextView 效果,相信大家一定熟悉跑马灯. 先来看看 Ellipsize是什么,Ellipsize 从开发技术上翻译为省略效果.故名思议,就是当文本无法显示全部时,用什么效果来显示未显示的部 ...

  9. Nginx设置黑名单

    date: 2019-07-04  14:35:56 author: headsen chen notice: 个人原创 1,在分域名下面设置: [root@pro-nginx:/usr/local/ ...

  10. SQL-W3School-函数:SQL MAX() 函数

    ylbtech-SQL-W3School-函数:SQL MAX() 函数 1.返回顶部 1. MAX() 函数 MAX 函数返回一列中的最大值.NULL 值不包括在计算中. SQL MAX() 语法 ...