批量下载文件一般使用循环的方式,逐一执行下载。但在带宽与服务器性能允许的情况下,使用多进程进行下载可以大大提高下载的效率。本文介绍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句柄

/**
* 多进程批量下载文件(使用php curl_multi_exec实现)
*
* Func
* public download 下载处理
* public process 多进程下载
* private to_log 将执行结果写入日志文件
*/
class DownLoad { // 下载文件设置
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

require 'DownLoad.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;

php利用curl实现多进程下载文件类的更多相关文章

  1. 学了C语言,如何利用CURL写一个下载程序?—用nmake编译CURL并安装

    在这一系列的前一篇文章学了C语言,如何为下载狂人写一个磁盘剩余容量监控程序?中,我们为下载狂人写了一个程序来监视磁盘的剩余容量,防止下载的东西撑爆了硬盘.可是,这两天,他又抱怨他的下载程序不好用,让我 ...

  2. PHP CURL实现远程下载文件到本地

    <?php //$result=httpcopy('http://www.phpernote.com/image/logo.gif'); echo '<pre>';print_r($ ...

  3. 转:Http下载文件类 支技断点续传功能

    using System; using System.Collections.Generic; using System.Text; using System.IO; using System.Net ...

  4. PHP使用CURL上传|下载文件

    CURL下载文件 /** * @param string $img_url 下载文件地址 * @param string $save_path 下载文件保存目录 * @param string $fi ...

  5. 在linux命令行利用SecureCRT上传下载文件

    一般来说,linux服务器大多是通过ssh客户端来进行远程的登陆和管理的,使用ssh登陆linux主机以后,如何能够快速的和本地机器进行文件的交互呢,也就是上传和下载文件到服务器和本地?与ssh有关的 ...

  6. Ubuntu 16.04利用SecureCRT上传/下载文件(sz/rz命令)

    说明:XShell同样也是支持的. 一.安装软件 sudo apt-get install lrzsz 二.sz下载文件用法: #下载一个文件 sz filename #下载多个文件 sz filen ...

  7. 利用chrome console批量下载文件

    因工作需要,需要定期从某页面下载多个文档,是体力活. 想用chrome扩展,找了几个不行.原因是: 1.有的扩展识别不了链接,因为链接是形如:jsp?XXX=XXX的形式 2.有的扩展能批量打开链接, ...

  8. Linux curl 命令下载文件

    引用自http://blog.csdn.net/wh211212/article/details/54285921 命令:curl 在Linux中curl是一个利用URL规则在命令行下工作的文件传输工 ...

  9. php curl下载文件由于空格导致下载文件失败

    <?php //$result=httpcopy('http://www.phpernote.com/image/logo.gif'); echo '<pre>';print_r($ ...

随机推荐

  1. ResourceNotFound: rgbd_launch

    Checking log directory for disk usage. This may take awhile. Press Ctrl-C to interrupt Done checking ...

  2. Hadoop平台的基本组成与生态系统

    Hadoop系统运行于一个由普通商用服务器组成的计算集群上,该服务器集群在提供大规模分布式数据存储资源的同时,也提供大规模的并行化计算资源. 在大数据处理软件系统上,随着Apache Hadoop系统 ...

  3. Java IO流-合并流

    2017-11-05 20:15:28 SequenceinputStream SequenceinputStream:SequenceInputStream 表示其他输入流的逻辑串联.它从输入流的有 ...

  4. DCOS(centos 7.4/7.6)

    https://dcos.io/releases/ https://downloads.dcos.io/dcos/stable/1.12.0/dcos_generate_config.sh https ...

  5. 2-13 搭建LAMP环境并部署Ucenter和Ucenter-home网站

    环境: VMware Virtual Machine : XGan63.cn IP: 192.168.31.63 (Bridge) 已配置本地yum源 ---> /mnt 已配置网络yum源 - ...

  6. HttpResponse 类

    而封闭HTTP输出信息的类型就是HttpResponse类,使用HttpResponse类可以实现三种类型的输出,即文本,URL,二进制流.  实现这三类的属性和方法分别介绍如下:1.文本的输出,在日 ...

  7. ARIMA模型——本质上是error和t-?时刻数据差分的线性模型!!!如果数据序列是非平稳的,并存在一定的增长或下降趋势,则需要对数据进行差分处理!ARIMA(p,d,q)称为差分自回归移动平均模型,AR是自回归, p为自回归项; MA为移动平均,q为移动平均项数,d为时间序列成为平稳时所做的差分次数

    https://www.cnblogs.com/bradleon/p/6827109.html 文章里写得非常好,需详细看.尤其是arima的举例! 可以看到:ARIMA本质上是error和t-?时刻 ...

  8. python自动化运维之路2

    list列表 列表是我们最以后最常用的数据类型之一,通过列表可以对数据实现最方便的存储.修改等操作 #!/usr/bin/env python # _*_ encoding:utf-8 _*_ # a ...

  9. halcon之屌炸天的自标定(2)

    自 halcon之屌炸天的自标定(1)发出以后,有朋友看了文章也应用到了自己的测量项目中,效果奇好,成功搞定了20um的需求,可喜可贺.   在halcon之屌炸天的自标定(1)中我提到了一片论文: ...

  10. springboot结合开源editor.md集成markdonw编辑器

    今天来实现一个简单的功能,通常blog后台编辑大多使用的是富文本编辑器,比如百度的Ueditor,比较轻巧的wangEditor,那么如何使用开源editor.md的markdown呢? 搭建一个sp ...