php开启多线程下载

php开启多线程下载


  
  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);
    }

}
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;
?>




查看原文:http://newmiracle.cn/?p=1885
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值