基于php+webuploader的大文件分片上传,支持断点续传,带进度条

基于php+webuploader的大文件分片上传,带进度条,支持断点续传(刷新、关闭页面、重新上传、网络中断等情况)。文件上传前先检测该文件是否已上传,如果已上传提示“文件已存在”,如果未上传则直接上传。视频上传时会根据设定的参数(分片大小、分片数量)进行上传,上传过程中会在目标文件夹中生成一个临时文件夹,用于存储临时分片,等所有分片上传完毕后,会根据序号重新组合成一个完整的视频,临时文件被删除。

如果文件上传至七牛云,可参看基于php大文件分片上传至七牛云,带进度条

首先下载webuploader

效果图:

基于php+webuploader的大文件分片上传,支持断点续传,带进度条_第1张图片

基于php+webuploader的大文件分片上传,支持断点续传,带进度条_第2张图片

 临时文件,用于存储分片

html代码

webuploader分片上传








选择文件

php请求后端

// 引用封装好的Upload类
use app\index\controller\Upload;
public function uploadVedio()
{
    $model =new Upload();
    $res = $model->doUpload();
    $model->ajaxReturn($res);

}

封装上传类

filepath = $this->filepath.$savePath;
        }
        #    #文件名称
      #  var_dump($postData);
        $postData['name'] =isset($postData['name'])?$postData['name']:'';
        $this->fileName =$postData['name'];
        if($this->isHaveFile()){
            $this->ajaxReturn(['status'=>299,'msg'=>'文件已存在!']);
        }

        $this->fileMd5 =$postData['fileMd5'];

        #允许文件的大小  1G
        $this->allowFileSize =(1*1024*1024*1024);

        if((int)$postData['size']>$this->allowFileSize){
            $this->ajaxReturn(['status'=>204,'msg'=>"文件大小超1G限制!"]);
        }
        #文件大小
        $this->totalSize=$postData['size'];
        $postData['chunks']=isset($postData['chunks'])?(int)$postData['chunks']:1;
        $postData['chunk']=isset($postData['chunk'])?(int)$postData['chunk']:0;
        if(!(int)$postData['chunks']){
            $this->ajaxReturn(['status'=>208,'msg'=>'chunks参数错误']);
        }

        #当前块
        $this->blobNum =$postData['chunk']+1;
        #总共块
        $this->totalBlobNum =$postData['chunks'];

        #获取后缀
        $fileExtension =explode(".",basename( $this->fileName));
        $this->fileExtension=array_pop($fileExtension);
        #检测后缀是否在允许范围
        $this->checkFileExtension();
        $this->nowFile =  $_FILES['file'];
        if( $this->nowFile['error'] > 0) {
            $msg['status'] = 502;
            $msg['msg'] = "文件错误!";
            $this->ajaxReturn($msg);
        }

    }
    public function doUpload(){
        #临时文件移动到指定目录下
        $res = $this->moveFile();
        if($res['status']==999){
            return $this->fileMerge();
        }else{
            return $res;
        }
    }

    #创建md5  文件名
    public function createFileName(){
        return $this->filepath.$this->fileName;
    }

    #检测文件是否重复
    public function isHaveFile(){
        if(file_exists($this->filepath.$this->fileName)){
            return true;
        }
        return false;
    }
    #文件合并
    public function fileMerge(){
        if ($this->blobNum == $this->totalBlobNum) {
            $fileName = $this->createFileName();
            @unlink($fileName);
            #删除旧文件
            #文件合并  文件名以
            $handle=fopen($fileName,"a+");
            for($i=1; $i<= $this->totalBlobNum; $i++){
                #当前分片数
                $this->blobNum = $i;
                #吧每个块的文件追加到 上传的文件中
                fwrite($handle,file_get_contents($this->createBlockFileName()));
            }
            fclose($handle);
            #删除分片
            for($i=1; $i<= $this->totalBlobNum; $i++){
                $this->blobNum = $i;
                @unlink($this->createBlockFileName());
            }
            #删除临时目录
            @rmdir($this->filepath.$this->fileMd5);
            if(filesize($fileName) == $this->totalSize){
                $msg['status'] = 200;
                $msg['msg'] = '上传成功!';
                $msg['size'] = $this->totalSize;
                $msg['filename'] = "http://".$_SERVER['HTTP_HOST']."/".$this->createFileName();
                $msg['name'] = $this->fileName;
            }else{
                $msg['status'] = 501;
                $msg['msg'] = '上传文件大小和总大小有误!';
                @unlink($this->createFileName());
            }
            return $msg;
            # $this->ajaxReturn($msg);
        }
    }
    #检测上传类型
    public function checkFileExtension(){
        if(!in_array(strtolower($this->fileExtension),$this->allowExtension)){
            $this->ajaxReturn(['status'=>203,'msg'=>"文件类型不允许"]);
        }
    }
    #将临时文件移动到指定目录
    public function moveFile(){
        try{
            #每个块的文件名 以文件名的MD5作为命名
            $filename=$this->createBlockFileName();
            #分片文件写入
            $handle=fopen($filename,"w+");
            fwrite($handle,file_get_contents($this->nowFile ['tmp_name']));
            fclose($handle);
            #不是最后一块就返回当前信息   是最后一块往下执行合并操作
            if($this->blobNum != $this->totalBlobNum) {
                $msg['status'] = 201;
                $msg['msg'] = "上传成功!";
                $msg['blobNum'] = $this->blobNum;
                return $msg;
                #$this->ajaxReturn($msg);
            }else{
                $msg['status'] = 999;
                $msg['msg'] = "上传成功!";
                $msg['blobNum'] = $this->blobNum;
                return $msg;
            }
        }catch (Exception $e){
            $msg['status'] = 501;
            $msg['error'] = $e->getMessage();
            return $msg;
            #$this->ajaxReturn($msg);
        }
    }
    #创建分片文件名
    public function createBlockFileName(){
        $dirName = $this->filepath.$this->fileMd5."/";
        if (!is_dir($dirName) ) {
            @mkdir($dirName, 0700);
        };
        return $dirName.$this->blobNum.".part";
    }

    #json格式放回处理
    public function ajaxReturn($msg){
        exit(json_encode($msg));
    }
}

你可能感兴趣的:(PHP,前端技术,php,javascript,视频)