php,js超简单的用easyswoole实现大文件分片上传

原理:简单来说,就是将前端需要上传的大文件拆分成为无数个小文件进行循环上传,后端接受的时候进行判断,往同一个文件里面添加,代码如下:

  • 前段
<input type="file" onchange="addAnnex('uploadAnnex-2')"  id="uploadAnnex-2"/>
<script>
//上传附件,监听input框onchange时间
function addAnnex(id) {
    var file = document.getElementById(id).files[0];
   	//调用分片上传方法
    PostFile(file,0,id);
}

//执行分片上传
function PostFile(file,i,domId,json){
	//获取上传参数
    var name = file.name,//文件名
        size = file.size,//文件大小                           
        shardSize = 1024 * 1024,//设置每个分片大小,我这是1M一个
        shardCount = Math.ceil(size / shardSize);//计算总片数

	//容错
    if(i >= shardCount){
        return;
    }

	//计算文件截取起始位置
    var start = i * shardSize;
    var end = start + shardSize;
    
    //将文件进行切片
    var packet = file.slice(start, end);

    //组织post表单数据
    var form = new FormData();

    form.append("name", name);
    form.append("upload", packet); //slice方法用于切出文件的一部分
    form.append("total", shardCount); //总片数
    form.append("index", i + 1); //当前是第几片

	//我这用这个变量标记当前传入的是否为第一片,存在值不是第一片,需要将之前的保存的文件名及需要的信息添加之表单数据中
    if(json){
        form.append('shard_name',json.name);
        form.append('id',json.id);
    }

	//开始上传
    $.ajax({
        url: baseUrl,//你的url
        type: "POST",
        data: form,
        async:false,
        timeout: 10000,
        processData: false,
        contentType: false,
        success: function (json) {
        	//等于200,全部上传完成
            if(json.code == 200){
                //此处实现你上传完成的逻辑
            }else if(json.code == 201){
            	//继续上传下一片,并将返回的结果加入到数据中
                form = '';
                i++;
                PostFile(file, i,domId,json.result);
            }else{
            	//出现错误
                jqtoast(json.msg);
            }
        },
        error: function (){
        }
    });
}
</script>
  • 后端 我使用了easyswoole框架,其实原理都一样
		//获取上传的文件数据
        $request=  $this->request();
        $file = $request->getUploadedFile('upload');
		//获取post删除
        $post = $this ->POST;

        //判断是否存在错误
        if($file ->getError()){
            return $this ->writeJson(401,'文件上传失败');
        }

        //限制文件大小,大于100M的不允许上传
        $size = $file -> getSize();
        if($size / (1024*1024) > 100){
            return $this ->writeJson(401,'文件太大了');
        }

        //判断是否传入分片文件名,不存在则表示上传第一片
        if(empty($post['shard_name'])){
            //获取文件后缀
            $ext = explode('.',$post['name']);
            $ext = array_pop($ext);

            //定义新的文件名
            $name = md5('product'.time());
            $name = substr($name,5,10).'.'.$ext;

            //定义文件保存路径
            $path = EASYSWOOLE_ROOT.'/Static/UploadFile/'.$name;

            //保存文件
            if(!($file -> moveTo($path))){
                return $this ->writeJson(400,'文件保存失败');
            }

            //组织保存数据
            $data = [
                'user_id'       => $uid,
                'product_id'    => 0,
                'name'          => $name,
                'src_name'      => $post['name'],
                'cdt'           => date('Y-m-d H:i:s')
            ];

            //验证数据是否保存成功
            try{
                $model = new File();
                $insertId = $model ->insert($data);
                if(empty($insertId)){
                    return $this ->writeJson(400,'文件上传失败');
                }
                $data['id'] = $insertId;
            }catch (\Exception $exception){
                Logger::getInstance()->error($exception ->getMessage(),'文件上传失败');
                return $this ->writeJson(400,'文件上传失败');
            }

            //组织返回数据
            $result = [
                'id'        => $insertId,
                'name'      => $name,
                'src_name'  => $post['name'],

            ];
        }else{
            //定义文件保存路径
            $path = EASYSWOOLE_ROOT.'/Static/UploadFile/'.$post['shard_name'];
            file_put_contents($path,$file->getStream(),FILE_APPEND);

            //组织返回数据
            $result = [
                'id'        => $post['id'],
                'name'      => $post['shard_name'],
                'src_name'  => $post['name'],
            ];
        }

        //判断是否上传完毕
        if($post['total'] == $post['index']){
            //上传完毕
            return $this ->writeJson(200,'ok',$result);
        }else{
            return $this ->writeJson(201,'ok',$result);
        }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值