搜索

查看: 3097|回复: 11

[PHP] PHP+JS实现文件分块上传的示例代码

[复制链接]
发表于 2023-5-4 17:07:23 | 显示全部楼层 |阅读模式
Editor 2023-5-4 17:07:23 3097 11 看全部
目录
  • 一、分块上传流程
  • 二、实现代码
  • HTML
  • JS
  • PHP我们在上传大文件时,可能会由于服务器的原因导致文件上传失败,文件过大时由于服务器的配置或响应事件过长导致上传文件失败,这时候我们可以将一个大的文件分为若干块,然后分批次上传到服务端,当所有文件块上传完成后再由服务器将各个文件块整合成我们上传的文件

    一、分块上传流程
    1:由前端js将上传的文件信息进行切割成若干块,然后循环将若干块的文件块上传到服务端
    2:服务端接收到文件块信息后保存起来,当所有文件块上传完毕后,将所有上传的文件块整合成文件并保存起来

    二、实现代码
    HTML




    上传进度:
    JS
    //获取节点
    var fileForm = document.getElementById("file");
    var uploadBtn = document.getElementById('upload');
    var stopBtn = document.getElementById('stop');
    var restartBtn = document.getElementById('restart');
    //定义常量
    const LENGTH = 100 * 1024;//每个上传的文件块大小(100KB)
    var start = 0;
    var end = LENGTH + start;
    var blob;
    var is_stop = 0;
    var blob_num = 1;
    var file = null;
    var upload_instance = new Upload();
    //上传事件
    uploadBtn.onclick = function () {
       upload_instance.addFileAndSend(fileForm);
       return false;
    }
    stopBtn.onclick = function () {
       upload_instance.stop();
       return false;
    }
    restartBtn.onclick = function () {
       upload_instance.start();
       return false;
    }
    function Upload() {
        //判断浏览器类型
        if (window.XMLHttpRequest){
            //IE7+, Firefox, Chrome, Opera, Safari
            var xhr=new XMLHttpRequest();
        }else{
            //IE6, IE5
            var xhr=new ActiveXObject("Microsoft.XMLHTTP");
        }
       //上传文件
       this.addFileAndSend = function (that) {
           file = that.files[0];
           blob = cutFile(file);
           //上传
           uploadFile(blob, file);
           blob_num += 1;
       }
       //停止文件上传
       this.stop = function () {
           xhr.abort();
           is_stop = 1;
       }
       this.start = function () {
           uploadFile(blob, file);
           is_stop = 0;
       }
       //切割文件
       function cutFile(file) {
           var file_blob = file.slice(start, end);
           start = end;
           end = start + LENGTH;
           return file_blob;
       };
        //上传文件
        function uploadFile(blob, file) {
            var form_data = new FormData();
            var total_blob_num = Math.ceil(file.size / LENGTH);
            //上传文件信息
            form_data.append('file', blob);
            //上传的第几个文件块
            form_data.append('blob_num', blob_num);
            //总文件块数
            form_data.append('total_blob_num', total_blob_num);
            //文件名称
            form_data.append('file_name', file.name);
            
            
            //上传
            xhr.open('POST', './test.php', false);
            xhr.onreadystatechange = function () {
                //获取上传进度
                if (total_blob_num == 1) {
                    progressText = '100%';
                } else {
                    progressText = (Math.min(100, (blob_num / total_blob_num) * 100)).toFixed(2) + '%';
                }
                var progress = document.getElementById('progress');
                progress.innerHTML = progressText;
                
                //循环执行上传,直到所有文件块上传完成
                var t = setTimeout(function () {
                    if (start
    PHP
    上传类
    class Upload
    {
        /**
         * @var string 上传目录
         */
        private $filepath = './upload'; //上传目录
        /**
         * @var string 块文件临时存储的位置
         */
        private $tmpPath;
        /**
         * @var integer 第几个文件块
         */
        private $blobNum;
        /**
         * @var integer //文件块总数
         */
        private $totalBlobNum;
        /**
         * @var string 上传文件名
         */
        private $fileName;
        public function __construct($tmpPath, $blobNum,$totalBlobNum,$fileName, $filepath = ''){
            if (!empty($filepath)) {
                $this->filepath = $filepath;
            }
            $this->tmpPath = $tmpPath;
            $this->blobNum = $blobNum;
            $this->totalBlobNum = $totalBlobNum;
            $this->fileName = $fileName;
            //保存文件块
            $this->moveFile();
            //保存文件
            $this->fileMerge();
        }
        private function fileMerge(){
            //当文件块都上传后将文件块整合成文件
            if($this->blobNum == $this->totalBlobNum){
                for($i=1; $itotalBlobNum; $i++){
                    $blob = '';
                    $blob = file_get_contents($this->filepath.'/'. $this->fileName.'__'.$i);
                    file_put_contents($this->filepath.'/'. $this->fileName, $blob, FILE_APPEND );
                    unset($blob);
                }
                //删除文件块
                $this->deleteFileBlob();
            }
        }
        //删除文件块
        private function deleteFileBlob(){
            for($i=1; $itotalBlobNum; $i++){
                @unlink($this->filepath.'/'. $this->fileName.'__'.$i);
            }
        }
        private function moveFile(){
            $this->touchDir();
            $filename = $this->filepath.'/'. $this->fileName.'__'.$this->blobNum;
            //保存文件块
             move_uploaded_file($this->tmpPath,$filename);
        }
        //上传返回
        public function uploadReturn(){
            if($this->blobNum == $this->totalBlobNum){
                if(file_exists($this->filepath.'/'. $this->fileName)){
                    return [
                        'code' => 2,
                        'message' => 'success',
                        'file_path' => 'http://'.$_SERVER['HTTP_HOST'].str_replace('.','',$this->filepath).'/'. $this->fileName,
                        'local_path' => str_replace('.','',$this->filepath).'/'. $this->fileName
                    ];
                }
            }
            return [
                'code' => 1,
                'message' => 'waiting',
            ];
        }
        /**
         * 创建目录
         */
        private function touchDir(){
            if(!file_exists($this->filepath)){
                return mkdir($this->filepath);
            }
        }
    }
    调用上传类
    $tmpName = $_FILES['file']['tmp_name'];
    $blobNum = $_POST['blob_num'];
    $totalBlobNum = $_POST['total_blob_num'];
    $fileName = $_POST['file_name'];
    $upload = new Upload($tmpName, $blobNum, $totalBlobNum, $fileName);
    $data = $upload->uploadReturn();
    header('Content-type: application/json');
    return json_encode($data);
    根据如上步骤就可以实现将文件分成若干块进行上传功能
    到此这篇关于PHP+JS实现文件分块上传的示例代码的文章就介绍到这了,更多相关PHP JS文件分块上传内容请搜索知鸟论坛以前的文章或继续浏览下面的相关文章希望大家以后多多支持知鸟论坛
  • 回复

    使用道具 举报

    发表于 2023-6-29 05:16:46 | 显示全部楼层
    伊索谗言 2023-6-29 05:16:46 看全部
    既然你诚信诚意的推荐了,那我就勉为其难的看看吧!知鸟论坛不走平凡路。
    回复

    使用道具 举报

    发表于 2023-6-29 18:38:59 | 显示全部楼层
    啤酒瓶空了缓 2023-6-29 18:38:59 看全部
    其实我一直觉得楼主的品味不错!呵呵!知鸟论坛太棒了!
    回复

    使用道具 举报

    发表于 2023-6-29 20:00:19 | 显示全部楼层
    哈哈SE7 2023-6-29 20:00:19 看全部
    既然你诚信诚意的推荐了,那我就勉为其难的看看吧!知鸟论坛不走平凡路。
    回复

    使用道具 举报

    发表于 2023-7-3 17:53:44 | 显示全部楼层
    术数古籍专卖疤 2023-7-3 17:53:44 看全部
    楼主,大恩不言谢了!知鸟论坛是最棒的!
    回复

    使用道具 举报

    发表于 2023-7-4 22:23:18 | 显示全部楼层
    尘埃416 2023-7-4 22:23:18 看全部
    感谢楼主的无私分享!要想知鸟论坛好 就靠你我他
    回复

    使用道具 举报

    发表于 2023-7-5 06:28:20 | 显示全部楼层
    执着等待等wc 2023-7-5 06:28:20 看全部
    感谢楼主的无私分享!要想知鸟论坛好 就靠你我他
    回复

    使用道具 举报

    发表于 2023-7-6 00:27:54 | 显示全部楼层
    落败的青春阳落s 2023-7-6 00:27:54 看全部
    这东西我收了!谢谢楼主!知鸟论坛真好!
    回复

    使用道具 举报

    发表于 2023-7-6 11:53:56 | 显示全部楼层
    十二音阶囤 2023-7-6 11:53:56 看全部
    其实我一直觉得楼主的品味不错!呵呵!知鸟论坛太棒了!
    回复

    使用道具 举报

    发表于 2023-7-6 20:22:32 | 显示全部楼层
    123456809 2023-7-6 20:22:32 看全部
    楼主,我太崇拜你了!我想我是一天也不能离开知鸟论坛
    回复

    使用道具 举报

    • 您可能感兴趣
    点击右侧快捷回复 【请勿灌水】
    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则 返回列表

    RSS订阅| SiteMap| 小黑屋| 知鸟论坛
    联系邮箱E-mail:zniao@foxmail.com
    快速回复 返回顶部 返回列表