PHP 之分片上传

一、效果图

二、前端

复制代码
<template>
    <div>
        <el-upload ref="uploadRef" 
        :show-file-list="false" 
        class="upload" 
        :auto-upload="false" 
        :on-change="handleChange"
        :limit="1" 
        :http-request="test"
        :on-exceed="test"
        >
            <el-button type="primary">文件上传</el-button>
        </el-upload>

        <el-progress :percentage="percent" :stroke-width="10" :status="status" />
    </div>
</template>

<script setup>
    import {
        getCurrentInstance,
        ref
    } from 'vue';
    
    const {proxy} = getCurrentInstance()
    const uploadRef = ref()
    
    const percent = ref(0)
    const status = ref('')

    const handleChange = (uploadFile, uploadFiles) => {
        console.log(uploadFile, uploadFiles, uploadFile.raw instanceof File)
        status.value = ''
        percent.value = 0
        
        const file = uploadFile.raw;
        const CHUNK_SIZE = 1024 * 1024 * 5; // 分片大小,例如5MB
        const CHUNKS = Math.ceil(file.size / CHUNK_SIZE); // 总分片数
        let uploaded = 0; // 已上传的分片数
        console.log(CHUNKS);

        const uploadChunk = async (chunkIndex) => {
            const start = chunkIndex * CHUNK_SIZE;
            const end = (chunkIndex + 1) * CHUNK_SIZE;
            const chunk = file.slice(start, end);
            const formData = new FormData();
            formData.append('file', chunk); // 注意:服务器端需要处理这种分片上传的情况
            formData.append('chunkIndex', chunkIndex); // 添加分片索引信息
            formData.append('totalChunks', CHUNKS); // 添加总分片数信息
            formData.append('fileName', file.name); // 可选,添加文件名信息
            
            console.log(chunk, formData)
            let res = await proxy.$http.post('upload.php', formData)
            console.log(res)
            if(res.code == 0) {
                uploaded++;
                updateProgress();
                //更新进度条
                if(chunkIndex + 1 == CHUNKS) {
                    console.log('上传成功 ==> ', res.fileInfo)
                    // alert(res.msg)
                    status.value = 'success';
                    uploadRef.value.clearFiles()
                }else{
                    uploadChunk(uploaded)
                }
            }else{
                console.log(res.msg);
            }
        }
        
        const updateProgress = () => {
            const percentVal = parseInt(parseFloat(uploaded / CHUNKS).toFixed(2) * 100)
            percent.value = percentVal
        }
        
        uploadChunk(0);
    }
    
    const test = (file) => {
        console.log(file)
    }
</script>

<style>
</style>

三、后端

复制代码
<?php

// var_dump($_FILES);
$chunkIndex = intval($_POST['chunkIndex']);
$fileName = trim($_POST['fileName']);
$totalChunks = intval($_POST['totalChunks']);

$ext = pathinfo($fileName, PATHINFO_EXTENSION);
$temp_name = md5($fileName).'_{0}.txt';
$uploadFile = str_replace('{0}', $chunkIndex, $temp_name);
if(move_uploaded_file($_FILES['file']['tmp_name'], $uploadFile)) {
    //合并文件
    $f = md5($fileName).'.'.$ext;
    if($chunkIndex + 1 == $totalChunks){
        $filesize = 0;
        for($i = 0; $i < $totalChunks; $i++){
            $file = str_replace('{0}', $i, $temp_name);
            if(file_exists($file)){
                //合并文件
                $content = file_get_contents($file);
                $filesize += strlen($content);
                file_put_contents($f, $content, FILE_APPEND);
                unlink($file);
            }
        }
        $fileInfo = array(
            'filename' => $fileName,
            'filesize' => $filesize,
            'path' => $f,
            'fileext' => $ext,
        );
        die(json_encode(array('code' => 0, 'msg' => '上传成功', 'fileInfo' => $fileInfo)));
    }
    die(json_encode(array('code' => 0, 'msg' => '上传成功')));
}else{
    die(json_encode(array('code' => 1, 'msg' => '上传失败')));
}
相关推荐
charlie1145141918 分钟前
嵌入式C++工程实践第16篇:第四次重构 —— LED模板,从通用GPIO到专用抽象
c语言·开发语言·c++·驱动开发·嵌入式硬件·重构
故事和你9115 分钟前
洛谷-数据结构1-4-图的基本应用1
开发语言·数据结构·算法·深度优先·动态规划·图论
程序猿编码1 小时前
给你的网络流量穿件“隐形衣“:手把手教你用对称加密打造透明安全隧道
linux·开发语言·网络·安全·linux内核
aq55356002 小时前
编程语言三巨头:汇编、C++与PHP大比拼
java·开发语言
aq55356002 小时前
PHP vs Python:30秒看懂核心区别
开发语言·python·php
我是无敌小恐龙2 小时前
Java SE 零基础入门Day01 超详细笔记(开发前言+环境搭建+基础语法)
java·开发语言·人工智能·opencv·spring·机器学习
FreeCultureBoy2 小时前
用 phpbrew 管理 php 环境:从安装到多版本切换
后端·php
码云数智-大飞3 小时前
零基础微信小程序制作平台哪个好
开发语言
神仙别闹3 小时前
基于 MATLAB 实现的 DCT 域的信息隐藏
开发语言·matlab
techdashen3 小时前
Go 标准库 JSON 包迎来重大升级:encoding/json/v2 实验版来了
开发语言·golang·json