如何利用phpcurl實現多進程下載檔案類

來源:互聯網
上載者:User

批量下載檔案一般使用迴圈的方式,逐一執行下載。但在頻寬與伺服器效能允許的情況下,使用多進程進行下載可以大大提高下載的效率。本文介紹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中文網。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.