单个文件下载时监控并控制下载速度 PHP

功能:1.将文件压缩下载 2.控制下载的速度 3. 实时提现下载速度

效果图:

代码如下:

<?php
    // argv 0=> 脚本的相对路径 1=>第一参数
    // 请求参数php urlstream.php http://127.0.0.1/example/temp.log
    if($argc <2){
        echo 'incomplete request parameters';die;
    }
    // 获取URL
    $url = $argv[1];

    // 宽带限制
    if($argc == 3){
        $max_kb_sec = $argv[2];
    }else{
        $max_kb_sec = 10;  // 单位kb/s
    }

    $severity_map = array(
        0=>'info',
        1=>'warning',
        2=>'error'
    );
    $timer = 0;
    //指向流事件的回调函数
    function notifier($code,$severity ,$msg,$xcode,$sofar,$max){
        global $term_sol,$severity_map,$max_kb_sec,$size,$timer;
        //当接收到PROGRESS事件时,不打印状态信息前缀
        if($code != STREAM_NOTIFY_PROGRESS){
            echo $severity_map[$severity].":";
        }
        switch ($code){
            // 链接资源后触发
            case STREAM_NOTIFY_CONNECT:
                print ("connected\n");
                $GLOBALS['begin_time'] = time()-0.001;
                break;
            // 当一个认证的请求完成,这个事件通过流的API触发
            case STREAM_NOTIFY_AUTH_REQUIRED:
                printf("authentication required:%s\n",trim($msg));
                break;
            // 告诉你是否成功认证或链接失败
            case STREAM_NOTIFY_AUTH_RESULT:
                printf("Logged in :%s\n",trim($msg));
            // http处理层在请求的响应中获得content-type头信息时触发
            case STREAM_NOTIFY_MIME_TYPE_IS:
                printf("Mime type:%s\n",$msg);
                break;
            // 当FTP层计算出文件的大小时触发或HTTP层看到content-length头信息触发
            case STREAM_NOTIFY_FILE_SIZE_IS:
                printf("Downloading %d kb\n",$max/1024);
                // 设置全局的宽度变量
                $size = $max;
                break;
            // HTTP处理层遇到重定向请求(location:header)时触发
            case STREAM_NOTIFY_REDIRECTED:
                printf("Redirecting to %s..\n",$msg);
                break;
            // 在数据包到达后迅速发送,在这个例子中我们执行贷款限制和进度条的显示
            case STREAM_NOTIFY_PROGRESS:
                // 计算星星标记和条纹数
                if($size){
                    $stars = str_repeat('*',$c=$sofar/$size*50);
                }else{
                    $stars = '';
                }
                $stripe = str_repeat('-',50-strlen($stars));
                //用kb/sec的单位计算下载速度
                $kb_sec = ($sofar / (time() - $GLOBALS['begin_time']))/1024;
                //echo "raw speed:".$kb_sec."__".$max_kb_sec."\n"; 查看原始速度
                // 如果超过了最高的输出速度,停止脚本
                while($kb_sec>$max_kb_sec) {
                    usleep(1);
                    $kb_sec = ($sofar/(time()-$GLOBALS['begin_time']))/1024;
                }
                //echo "current speed:".$kb_sec."__".$max_kb_sec."\n";查看限制后的速度
                //显示进度条
                $timer++;
                printf("[%s]%d kb %.lf kb/sec\n\n",$stars.$stripe,$sofar/1024,$kb_sec);
                break;
            // 显示错误信息,例如签名错误
            case STREAM_NOTIFY_FAILURE:
                printf("Failure:%s\n",$msg);
                break;
        }
    }

    // 同时确定保存的文件名
    $url_data = parse_url($argv[1]);     // 拆分路径
    $file = basename($url_data['path']);
    if(empty($file)){
        $file = 'form.html';
    }
    printf("saving to $file.gz\n");
    $fil = "compress.zlib://$file.gz";
    //创建上下文并且设置notifier的回调函数
    $context = stream_context_create();
    stream_context_set_params($context,array("notification"=>"notifier"));
    //打开目标文件
    $fp = fopen($url,"rb",false,$context);
    if(is_resource($fp)){
        // 打开本地文件
        $fs = fopen($fil,"wb",false,$context);
        if(is_resource($fs)){
            // 从URL以每块1024字节来读取数据
            $i = 0;
            while(!feof($fp)){
                $data = fgets($fp,1024);
                fwrite($fs,$data);
            }
            // 关闭远程文件
            fclose($fs);
        }
        fclose($fp);
        printf("[%s] Download time:%ds\n",str_repeat('*',50),time()-$GLOBALS['begin_time']);
    }

 

おすすめ

転載: blog.csdn.net/qq_24973351/article/details/109062881