PHP关于大文件切片上传的思路与实践体会--前端jquery、后端php

刚开始直接对file源文件进行的slice切片,但是这样的切片到后端处理着稍微有点麻烦,所以我就试着用base64进行切片,效果很不错,减少了工作量,也提高了效率。

思路

先用jquery对文件进行base64转换,得到base64编码,然后计算base64的长度,用slice方法每次截取固定的长度,放到数组中,然后循环数组的同时把base64切片依次传到后端,在后端可以把切片临时存储到cookie或者session中,当然redis之类的技术也可以,哪个方便用哪个,到最后把所有切片拼接起来,可以通过oss传到对象服务器或者其他地方,这都不用多说了。

代码实现

jquery前端切片实现代码:

//图片转base64
function BlobToBase64(blob) {
    return new Promise(function (resolve) {
        const reader = new FileReader()
        reader.readAsDataURL(blob)
        reader.onload = function () {
            resolve(this.result)
        }
    })
}

//转化base64格式
BlobToBase64(file).then((res) => {
    var arr = [];
    //设置每个切片的长度
    const ChunkSize = 1024 * 1024 * 3;
    //截取开始的位置
    var start = 0;
    //截取结束的位置
    var end = ChunkSize;
    while (start < res.length) {
        //截取出来的字符串放到arr中
        arr.push(res.slice(start, end))
        start = end;
        end = start + ChunkSize;
    }
    //设置当前传给后端的切片序号
    var file_index = 0;
    //循环切片,依次传给后端
    arr.map((itm, idx) => {
        file_index++;
        $.post("Your Url", {
            base64: itm,
            file_index: file_index,
            total: arr.length  //切片总数
        }, function (res) {


        })
    })
})

php后端接收切片代码:

/**
     * 文件上传.
     *
     * @return [type] [description]
     */
    public function uploadfile()
    {
        try {
            $post = $_POST;

            $imageBase64Data = $post['base64'];
            //把接收到的切片临时存储到session中,以数组的形式,键名为前端传过来的切片序号,键值为切片内容,当然这里建议用其它方式存储,比如redis之类的
            $_SESSION['upload_base64'][$post['file_index']] = $imageBase64Data;
            //存储接收到的切片总数
            $_SESSION['upload_base64_total']++;


            //判断接收到的切片总数是否等于前端传过来的切片总数,如果不等于则返回一个上传进度
            if ($_SESSION['upload_base64_total'] != ($post['total'])) {

                $percent = $_SESSION['upload_base64_total'] / ($post['total']);
                if ($percent>1){
                    $_SESSION['upload_base64_total'] = 0;
                    $_SESSION['upload_base64'] = [];
                }
                return ['code' => 2, 'msg' => '上传进度' . ($percent * 100) . "%"];
            }

            //根据切片序号进行排序,因为jquery是异步执行的,所以顺序可能是乱的
            ksort($_SESSION['upload_base64']);

            $upload_base64 = '';
            
            //循环拼接出原始的base64编码
            foreach ($_SESSION['upload_base64'] as $base64) {
                $upload_base64 .= $base64;
            }

            //清空session
            $_SESSION['upload_base64_total'] = 0;
            $_SESSION['upload_base64'] = [];

            //这里用的阿里云的OSS、base64的上传方式
            $oss = new Oss();
            $res = $oss->uploadFileBase64($upload_base64, time() . rand(9999, 999999) . $post['filename']);

            if ($res['code'] == 0) {
                $url = $res['url'];
            } else {
                return json($res);
            }
            $data = [
                "code" => 0,
                "msg" => "上传成功",
                "data" => $url
            ];
        } catch (\Exception $e) {
            $data = ['code' => -1, 'msg' => $e->getMessage()];
        }
        return $data;
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

对这是我的昵称

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值