基於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
  • Dapr Outbox 是1.12中的功能。 本文只介紹Dapr Outbox 執行流程,Dapr Outbox基本用法請閱讀官方文檔 。本文中appID=order-processor,topic=orders 本文前提知識:熟悉Dapr狀態管理、Dapr發佈訂閱和Outbox 模式。 Outbo ...
  • 引言 在前幾章我們深度講解了單元測試和集成測試的基礎知識,這一章我們來講解一下代碼覆蓋率,代碼覆蓋率是單元測試運行的度量值,覆蓋率通常以百分比表示,用於衡量代碼被測試覆蓋的程度,幫助開發人員評估測試用例的質量和代碼的健壯性。常見的覆蓋率包括語句覆蓋率(Line Coverage)、分支覆蓋率(Bra ...
  • 前言 本文介紹瞭如何使用S7.NET庫實現對西門子PLC DB塊數據的讀寫,記錄了使用電腦模擬,模擬PLC,自至完成測試的詳細流程,並重點介紹了在這個過程中的易錯點,供參考。 用到的軟體: 1.Windows環境下鏈路層網路訪問的行業標準工具(WinPcap_4_1_3.exe)下載鏈接:http ...
  • 從依賴倒置原則(Dependency Inversion Principle, DIP)到控制反轉(Inversion of Control, IoC)再到依賴註入(Dependency Injection, DI)的演進過程,我們可以理解為一種逐步抽象和解耦的設計思想。這種思想在C#等面向對象的編 ...
  • 關於Python中的私有屬性和私有方法 Python對於類的成員沒有嚴格的訪問控制限制,這與其他面相對對象語言有區別。關於私有屬性和私有方法,有如下要點: 1、通常我們約定,兩個下劃線開頭的屬性是私有的(private)。其他為公共的(public); 2、類內部可以訪問私有屬性(方法); 3、類外 ...
  • C++ 訪問說明符 訪問說明符是 C++ 中控制類成員(屬性和方法)可訪問性的關鍵字。它們用於封裝類數據並保護其免受意外修改或濫用。 三種訪問說明符: public:允許從類外部的任何地方訪問成員。 private:僅允許在類內部訪問成員。 protected:允許在類內部及其派生類中訪問成員。 示 ...
  • 寫這個隨筆說一下C++的static_cast和dynamic_cast用在子類與父類的指針轉換時的一些事宜。首先,【static_cast,dynamic_cast】【父類指針,子類指針】,兩兩一組,共有4種組合:用 static_cast 父類轉子類、用 static_cast 子類轉父類、使用 ...
  • /******************************************************************************************************** * * * 設計雙向鏈表的介面 * * * * Copyright (c) 2023-2 ...
  • 相信接觸過spring做開發的小伙伴們一定使用過@ComponentScan註解 @ComponentScan("com.wangm.lifecycle") public class AppConfig { } @ComponentScan指定basePackage,將包下的類按照一定規則註冊成Be ...
  • 操作系統 :CentOS 7.6_x64 opensips版本: 2.4.9 python版本:2.7.5 python作為腳本語言,使用起來很方便,查了下opensips的文檔,支持使用python腳本寫邏輯代碼。今天整理下CentOS7環境下opensips2.4.9的python模塊筆記及使用 ...