基於php+webuploader的大文件分片上傳,支持斷點續傳,帶進度條

来源:https://www.cnblogs.com/zxf100/archive/2023/02/03/17089739.html
-Advertisement-
Play Games

基於php+webuploader的大文件分片上傳,帶進度條,支持斷點續傳(刷新、關閉頁面、重新上傳、網路中斷等情況)。文件上傳前先檢測該文件是否已上傳,如果已上傳提示“文件已存在”,如果未上傳則直接上傳。視頻上傳時會根據設定的參數(分片大小、分片數量)進行上傳,上傳過程中會在目標文件夾中生成一個臨 ...


基於php+webuploader的大文件分片上傳,帶進度條,支持斷點續傳(刷新、關閉頁面、重新上傳、網路中斷等情況)。文件上傳前先檢測該文件是否已上傳,如果已上傳提示“文件已存在”,如果未上傳則直接上傳。視頻上傳時會根據設定的參數(分片大小、分片數量)進行上傳,上傳過程中會在目標文件夾中生成一個臨時文件夾,用於存儲臨時分片,等所有分片上傳完畢後,會根據序號重新組合成一個完整的視頻,臨時文件被刪除。

如果文件上傳至七牛雲,可參看基於php大文件分片上傳至七牛雲,帶進度條

首先下載webuploader

效果圖:

 

 臨時文件,用於存儲分片

 

 

html代碼

<title>webuploader分片上傳</title>
<meta charset="utf8">
<!--引入CSS-->
<link rel="stylesheet" type="text/css" href="/static/webupload/webuploader.css">
<script type="text/javascript" src="/static/index/js/jquery.js"></script>
<script type="text/javascript" src="/static/index/js/jquery.md5.js"></script>

<!--引入JS-->
<script type="text/javascript" src="/static/webupload/webuploader.js"></script>
<div id="uploader" class="wu-example">
    <!--用來存放文件信息-->
    <div id="thelist" class="uploader-list"></div>
    <div class="btns">
        <div id="picker">選擇文件</div>
        <button id="ctlBtn" class="btn btn-default">開始上傳</button>
    </div>
</div>
<style>
    .progress{
        height: 20px; width: 300px; background: #ccc; }
    .progress-bar{
        height: 20px; background: #0a3536;}
</style>
<script>

    var uploadswf = '/static/webupload/Uploader.swf';
    var chunkSize = 2*1024*1024;
    var server_url='uploadVedio';
    var GUID = WebUploader.Base.guid();//一個GUID
    var chunkObj = {};  //用來記錄文件的狀態、上傳中斷的位置
    var seq=1;
    var msg='';
    $(function () {
        var $ = jQuery;
        var $list = $('#thelist');
        WebUploader.Uploader.register({
            "before-send-file":"beforeSendFile",
            "before-send": "beforeSend"
        }, {
            "beforeSendFile": function (file) {
                //上傳前校驗文件是否已經上傳過
                var deferred = WebUploader.Deferred();
                $.ajax({
                    type:"POST",
                    //上傳前校驗文件上傳到第幾片
                    url: "checkFile",
                    data: {
                        seq: seq,
                        fileMd5: $.md5(file.name + file.size + file.ext),
                        fileName:file.name
                    },
                    dataType: "json",
                    success: function (data) {
                        console.log(data);
                        chunkObj = data;
                        chunkObj.type = data.type;
                        chunkObj.chunk == data.chunk;
                        msg = data.msg;
                        if(data.type==404){
                            deferred.reject();
                            $("#" + file.id).find(".state").text(data.msg);
                        }else if (data.type == 0) {
                            deferred.reject();
                            $("#" + file.id).find(".state").text("文件已上傳");
                        } else if (data.type == 1) {
                            if (data.chunk) {
                                deferred.resolve();
                            }
                        } else {
                            deferred.resolve();
                        }

                    },
                    error: function () {
                        deferred.resolve();
                    }
                })
                //deferred.resolve();
                return deferred.promise();
            },
            "beforeSend": function (block) {
                var deferred = WebUploader.Deferred();
                var curChunk = block.chunk;
                var totalChunk = block.chunks;
                console.log(chunkObj)
                if (chunkObj.type == "1") {
                    if (curChunk < chunkObj.chunk) {
                        deferred.reject();
                    } else {
                        deferred.resolve();
                    }
                } else {
                    deferred.resolve();
                }
                return deferred.promise();
            }
        });
        var uploader = WebUploader.create({
            // 選完文件後,是否自動上傳。
            auto: false,
            // swf文件路徑
            swf: uploadswf,
            // 文件接收服務端。
            server: server_url,
            // 內部根據當前運行是創建,可能是input元素,也可能是flash.
            pick: '#picker',
            chunked: true,//開始分片上傳
            chunkSize:1 * 1024 * 1024,//每一片的大小
            threads: 1,
            formData: {
            },

            // 不壓縮image, 預設如果是jpeg,文件上傳前會壓縮一把再上傳!
            resize: false
        });

        // 當有文件被添加進隊列的時候
        uploader.on('fileQueued', function (file) {

            $list.append('<div id="' + file.id + '" class="item">' +
                '<div class="item-file"><div class="fileType-logo"></div>' +
                '<div class="fileMes"><h4 class="info">' + file.name + '</h4>' +
                '<p class="state">等待上傳...</p>' +
                '</div></div></div>');

        });
        // 文件上傳過程中創建進度條實時顯示。
        uploader.on('uploadProgress', function (file, percentage) {
            var $li = $('#' + file.id),
                $percent = $li.find('.progress .progress-bar');
            // 避免重覆創建
            if (!$percent.length) {
                $percent = $('<div class="progress progress-striped active">' +
                    '<div class="progress-bar" role="progressbar" style="width: 0%">' +
                    '</div>' +
                    '</div>').appendTo($li).find('.progress-bar');
            }
            $li.find('p.state').text('上傳中');
            $percent.css('width', percentage * 100 + '%');
        });
        uploader.on("uploadBeforeSend", function (obj, data, headers) {
            var file = obj.cuted.file;


            data.test = 1;
            data.fileMd5 = $.md5(file.name + file.size + file.ext);


        })
        // 文件上傳成功,給item添加成功class, 用樣式標記上傳成功。
        uploader.on('uploadSuccess', function (file, response) {
            if(response.status==299){
                $('#' + file.id).find('p.state').text('文件已存在');
            }else{
                $('#' + file.id).find('p.state').text('已上傳');
            }

        });
        // 文件上傳失敗,顯示上傳出錯。
        uploader.on('uploadError', function (file) {
            $('#' + file.id).find('p.state').text(msg);
        });
        // 完成上傳完了,成功或者失敗,先刪除進度條。
        uploader.on('uploadComplete', function (file) {
            $('#' + file.id).find('.progress').fadeOut();
        });
        //所有文件上傳完畢
        uploader.on("uploadFinished", function () {
            //提交表單
        });
        //開始上傳
        $("#ctlBtn").click(function () {
            uploader.upload();

        });
    });

</script>

php請求後端

use app\index\controller\Upload;
public
function uploadVedio() { $model =new Upload(); $res = $model->doUpload(); $model->ajaxReturn($res); }

封裝上傳類

<?php
namespace app\index\controller;
use think\Controller;

/**
 * 大文件分片上傳
 */
class Upload extends Controller
{
    
    
    private $filepath = 'uploads/'; //上傳目錄
    private $blobNum; //第幾個文件塊
    private $totalBlobNum; //文件塊總數
    private $fileName; //文件名
    #允許上傳的文件
    private $allowExtension = ['mp4','avi','wmv'];
    #文件尾碼
    private $fileExtension ='';
    #當前塊內容
    private $nowFile = '';
    #文件大小
    private $totalSize = 0;
    #文件總大小隻允許1G
    private $allowFileSize = 0;
    #文件md5  前端傳過來的   用於創建臨時文件夾  上傳完後刪除
    private $fileMd5='';

    public function __construct($savePath =''){
        $postData = $_POST;
        #測試斷點上傳
        if(isset($postData['test'])){
            sleep(1);
        }
        if($savePath){
            $this->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']=	   

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 前言 前面我們已經學習了Python的基礎語法,瞭解了Python的分支結構,也就是選擇結構、迴圈結構以及函數這些具體的框架,還學習了列表、元組、字典、字元串這些Python中特有的數據結構,還用這些語法完成了一個簡單的名片管理系統。下麵我就將介紹一下Python的一些進階語法規則,為後面更複雜的編 ...
  • Map 介面與 Collection 併列存在的,用於保存具有映射關係的數據:key-value 被稱為 鍵值對 。Java集合可分為 Collection 和 Map 兩種體系。Map 中的 key 和 value 都可以是任何引用類型的數據。Map 中的 key 用 Set 集合存儲的,不允許... ...
  • 鋼鐵知識庫,一個學習python爬蟲、數據分析的知識庫。人生苦短,快用python。 使用pycharm創建python文件時候,有時候需要自動生成想要的文件頭,如何生成呢? 只需要以下幾步: 在file->settings中搜索temp,找到file and code templates->pyt ...
  • Java集合框架 每博一文案 《殺死一隻知更鳥》中有這樣一段話:“你永遠不可能真正地瞭解一個人,除非你穿上他的鞋子走來走去,站在他的角度思考問題。 可真當你走過他的路時,你連路過都覺得難過。” 世上沒有真正的感同身受,也永遠不會有一模一樣的境遇。 很多時候,你以為看到了全貌,但其實只有冰山一角。永遠 ...
  • 最大公約數演算法不是很無聊,計算最大公約數是數學中一個重要的概念,可以用於判斷兩個數是否互質、求分數的約分等,在很多領域都有廣泛的應用。具體如下: 判斷兩個數是否互質:兩個數的最大公約數為1,說明這兩個數是互質的。 求分數的約分:將分子和分母的最大公約數約分掉,使得分數的值不變。 求同餘方程的最小正整 ...
  • 聲明 本文章中所有內容僅供學習交流,抓包內容、敏感網址、數據介面均已做脫敏處理,嚴禁用於商業用途和非法用途,否則由此產生的一切後果均與作者無關,若有侵權,請聯繫我立即刪除! 本文章未經許可禁止轉載,禁止任何修改後二次傳播,擅自使用本文講解的技術而導致的任何意外,作者均不負責,若有侵權,請在公眾號【K ...
  • BP(Back Propagation)演算法是一種常用的神經網路訓練演算法,主要用於識別分類和預測。常用於圖像識別、語音識別、文本分類等場景。它的原理是通過對誤差進行反向傳播來更新網路的參數,使得模型的誤差最小。BP演算法最早於1986年由Rumelhart等人提出。BP演算法適用於處理非線性問題,並且不 ...
  • 基於php大文件分片上傳至七牛雲,使用的是七牛雲js-sdk V2版本,引入js文件,配置簡單,可以暫停,暫停後支持斷點續傳(刷新、關閉頁面、重新上傳、網路中斷等情況),可以配置分片大小和分片數量,官方文檔https://developer.qiniu.com/kodo/6889/javascrip ...
一周排行
    -Advertisement-
    Play Games
  • 前言 在我們開發過程中基本上不可或缺的用到一些敏感機密數據,比如SQL伺服器的連接串或者是OAuth2的Secret等,這些敏感數據在代碼中是不太安全的,我們不應該在源代碼中存儲密碼和其他的敏感數據,一種推薦的方式是通過Asp.Net Core的機密管理器。 機密管理器 在 ASP.NET Core ...
  • 新改進提供的Taurus Rpc 功能,可以簡化微服務間的調用,同時可以不用再手動輸出模塊名稱,或調用路徑,包括負載均衡,這一切,由框架實現並提供了。新的Taurus Rpc 功能,將使得服務間的調用,更加輕鬆、簡約、高效。 ...
  • 順序棧的介面程式 目錄順序棧的介面程式頭文件創建順序棧入棧出棧利用棧將10進位轉16進位數驗證 頭文件 #include <stdio.h> #include <stdbool.h> #include <stdlib.h> 創建順序棧 // 指的是順序棧中的元素的數據類型,用戶可以根據需要進行修改 ...
  • 前言 整理這個官方翻譯的系列,原因是網上大部分的 tomcat 版本比較舊,此版本為 v11 最新的版本。 開源項目 從零手寫實現 tomcat minicat 別稱【嗅虎】心有猛虎,輕嗅薔薇。 系列文章 web server apache tomcat11-01-官方文檔入門介紹 web serv ...
  • C總結與剖析:關鍵字篇 -- <<C語言深度解剖>> 目錄C總結與剖析:關鍵字篇 -- <<C語言深度解剖>>程式的本質:二進位文件變數1.變數:記憶體上的某個位置開闢的空間2.變數的初始化3.為什麼要有變數4.局部變數與全局變數5.變數的大小由類型決定6.任何一個變數,記憶體賦值都是從低地址開始往高地 ...
  • 如果讓你來做一個有狀態流式應用的故障恢復,你會如何來做呢? 單機和多機會遇到什麼不同的問題? Flink Checkpoint 是做什麼用的?原理是什麼? ...
  • C++ 多級繼承 多級繼承是一種面向對象編程(OOP)特性,允許一個類從多個基類繼承屬性和方法。它使代碼更易於組織和維護,並促進代碼重用。 多級繼承的語法 在 C++ 中,使用 : 符號來指定繼承關係。多級繼承的語法如下: class DerivedClass : public BaseClass1 ...
  • 前言 什麼是SpringCloud? Spring Cloud 是一系列框架的有序集合,它利用 Spring Boot 的開發便利性簡化了分散式系統的開發,比如服務註冊、服務發現、網關、路由、鏈路追蹤等。Spring Cloud 並不是重覆造輪子,而是將市面上開發得比較好的模塊集成進去,進行封裝,從 ...
  • class_template 類模板和函數模板的定義和使用類似,我們已經進行了介紹。有時,有兩個或多個類,其功能是相同的,僅僅是數據類型不同。類模板用於實現類所需數據的類型參數化 template<class NameType, class AgeType> class Person { publi ...
  • 目錄system v IPC簡介共用記憶體需要用到的函數介面shmget函數--獲取對象IDshmat函數--獲得映射空間shmctl函數--釋放資源共用記憶體實現思路註意 system v IPC簡介 消息隊列、共用記憶體和信號量統稱為system v IPC(進程間通信機制),V是羅馬數字5,是UNI ...