php利用curl实现多进程下载文件类

分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow

也欢迎大家转载本篇文章。分享知识,造福人民,实现我们中华民族伟大复兴!

                       

批量下载文件一般使用循环的方式,逐一执行下载。但在带宽与服务器性能允许的情况下,使用多进程进行下载可以大大提高下载的效率。本文介绍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);    }}?>
   
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173

 
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;?>
   
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

 
执行后日志输出

[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
   
   
  • 1
  • 2
  • 3
  • 4
  • 5



源码下载地址:点击查看

           

给我老师的人工智能教程打call!http://blog.csdn.net/jiangjunshow

这里写图片描述

猜你喜欢

转载自blog.csdn.net/hsyyff/article/details/84195710