源码论坛公告:本站是一个交流学习建站资源的社区论坛,旨在交流学习源码脚本等资源技术,欢迎大家投稿发言! 【点击此处将锦尚放在桌面

源码论坛,商业源码下载,尽在锦尚中国商业源码论坛

 找回密码
 会员注册

QQ登录

只需一步,快速开始

查看: 6013|回复: 0

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

[复制链接]

3123

主题

3525

帖子

14万

金币

超级版主

Rank: 8Rank: 8

积分
287186
发表于 2022-12-26 20:13:24 | 显示全部楼层 |阅读模式
在上传大文件时,可能会由于服务器的原因导致文件上传失败,文件过大时由于服务器的配置或响应事件过长导致上传文件失败,这时候我们可以将一个大的文件分为若干块,然后分批次上传到服务端。本文介绍了实现的方法,需要的可以参考一下


我们在上传大文件时,可能会由于服务器的原因导致文件上传失败,文件过大时由于服务器的配置或响应事件过长导致上传文件失败,这时候我们可以将一个大的文件分为若干块,然后分批次上传到服务端,当所有文件块上传完成后再由服务器将各个文件块整合成我们上传的文件

一、分块上传流程

1:由前端js将上传的文件信息进行切割成若干块,然后循环将若干块的文件块上传到服务端

2:服务端接收到文件块信息后保存起来,当所有文件块上传完毕后,将所有上传的文件块整合成文件并保存起来

二、实现代码

HTML

  1. <input type="file" id="file">
  2. <input type="button" id="upload" value="上传">
  3. <input type="button" id="stop" value="停止">
  4. <input type="button" id="restart" value="继续上传">
  5. 上传进度:<span id="progress"></span>
复制代码


JS

  1. //获取节点
  2. var fileForm = document.getElementById("file");
  3. var uploadBtn = document.getElementById('upload');
  4. var stopBtn = document.getElementById('stop');
  5. var restartBtn = document.getElementById('restart');
  6. //定义常量
  7. const LENGTH = 100 * 1024;//每个上传的文件块大小(100KB)
  8. var start = 0;
  9. var end = LENGTH + start;
  10. var blob;
  11. var is_stop = 0;
  12. var blob_num = 1;
  13. var file = null;
  14. var upload_instance = new Upload();
  15. //上传事件
  16. uploadBtn.onclick = function () {
  17.    upload_instance.addFileAndSend(fileForm);
  18.    return false;
  19. }
  20. stopBtn.onclick = function () {
  21.    upload_instance.stop();
  22.    return false;
  23. }
  24. restartBtn.onclick = function () {
  25.    upload_instance.start();
  26.    return false;
  27. }
  28. function Upload() {
  29.     //判断浏览器类型
  30.     if (window.XMLHttpRequest){
  31.         //IE7+, Firefox, Chrome, Opera, Safari
  32.         var xhr=new XMLHttpRequest();
  33.     }else{
  34.         //IE6, IE5
  35.         var xhr=new ActiveXObject("Microsoft.XMLHTTP");
  36.     }
  37.    //上传文件
  38.    this.addFileAndSend = function (that) {
  39.        file = that.files[0];
  40.        blob = cutFile(file);
  41.        //上传
  42.        uploadFile(blob, file);
  43.        blob_num += 1;
  44.    }
  45.    //停止文件上传
  46.    this.stop = function () {
  47.        xhr.abort();
  48.        is_stop = 1;
  49.    }
  50.    this.start = function () {
  51.        uploadFile(blob, file);
  52.        is_stop = 0;
  53.    }
  54.    //切割文件
  55.    function cutFile(file) {
  56.        var file_blob = file.slice(start, end);
  57.        start = end;
  58.        end = start + LENGTH;
  59.        return file_blob;
  60.    };
  61.     //上传文件
  62.     function uploadFile(blob, file) {
  63.         var form_data = new FormData();
  64.         var total_blob_num = Math.ceil(file.size / LENGTH);
  65.         //上传文件信息
  66.         form_data.append('file', blob);
  67.         //上传的第几个文件块
  68.         form_data.append('blob_num', blob_num);
  69.         //总文件块数
  70.         form_data.append('total_blob_num', total_blob_num);
  71.         //文件名称
  72.         form_data.append('file_name', file.name);
  73.         
  74.         
  75.         //上传
  76.         xhr.open('POST', './test.php', false);
  77.         xhr.onreadystatechange = function () {
  78.             //获取上传进度
  79.             if (total_blob_num == 1) {
  80.                 progressText = '100%';
  81.             } else {
  82.                 progressText = (Math.min(100, (blob_num / total_blob_num) * 100)).toFixed(2) + '%';
  83.             }
  84.             var progress = document.getElementById('progress');
  85.             progress.innerHTML = progressText;
  86.             
  87.             //循环执行上传,直到所有文件块上传完成
  88.             var t = setTimeout(function () {
  89.                 if (start < file.size && is_stop == 0) {
  90.                     blob = cutFile(file);
  91.                     uploadFile(blob, file);
  92.                     blob_num += 1;
  93.                 } else {
  94.                     //所有文件块上传完成
  95.                 }
  96.             }, 1000);
  97.         }
  98.         xhr.send(form_data);
  99.         //每次文件块上传后,清空上传信息
  100.         form_data = "";
  101.     }
  102. }
复制代码


PHP

上传类

  1. class Upload
  2. {
  3.     /**
  4.      * @var string 上传目录
  5.      */
  6.     private $filepath = './upload'; //上传目录
  7.     /**
  8.      * @var string 块文件临时存储的位置
  9.      */
  10.     private $tmpPath;
  11.     /**
  12.      * @var integer 第几个文件块
  13.      */
  14.     private $blobNum;
  15.     /**
  16.      * @var integer //文件块总数
  17.      */
  18.     private $totalBlobNum;
  19.     /**
  20.      * @var string 上传文件名
  21.      */
  22.     private $fileName;
  23.     public function __construct($tmpPath, $blobNum,$totalBlobNum,$fileName, $filepath = ''){
  24.         if (!empty($filepath)) {
  25.             $this->filepath = $filepath;
  26.         }
  27.         $this->tmpPath = $tmpPath;
  28.         $this->blobNum = $blobNum;
  29.         $this->totalBlobNum = $totalBlobNum;
  30.         $this->fileName = $fileName;
  31.         //保存文件块
  32.         $this->moveFile();
  33.         //保存文件
  34.         $this->fileMerge();
  35.     }
  36.     private function fileMerge(){
  37.         //当文件块都上传后将文件块整合成文件
  38.         if($this->blobNum == $this->totalBlobNum){
  39.             for($i=1; $i<= $this->totalBlobNum; $i++){
  40.                 $blob = '';
  41.                 $blob = file_get_contents($this->filepath.'/'. $this->fileName.'__'.$i);
  42.                 file_put_contents($this->filepath.'/'. $this->fileName, $blob, FILE_APPEND );
  43.                 unset($blob);
  44.             }
  45.             //删除文件块
  46.             $this->deleteFileBlob();
  47.         }
  48.     }
  49.     //删除文件块
  50.     private function deleteFileBlob(){
  51.         for($i=1; $i<= $this->totalBlobNum; $i++){
  52.             @unlink($this->filepath.'/'. $this->fileName.'__'.$i);
  53.         }
  54.     }
  55.     private function moveFile(){
  56.         $this->touchDir();
  57.         $filename = $this->filepath.'/'. $this->fileName.'__'.$this->blobNum;
  58.         //保存文件块
  59.          move_uploaded_file($this->tmpPath,$filename);
  60.     }
  61.     //上传返回
  62.     public function uploadReturn(){
  63.         if($this->blobNum == $this->totalBlobNum){
  64.             if(file_exists($this->filepath.'/'. $this->fileName)){
  65.                 return [
  66.                     'code' => 2,
  67.                     'message' => 'success',
  68.                     'file_path' => 'http://'.$_SERVER['HTTP_HOST'].str_replace('.','',$this->filepath).'/'. $this->fileName,
  69.                     'local_path' => str_replace('.','',$this->filepath).'/'. $this->fileName
  70.                 ];
  71.             }
  72.         }
  73.         return [
  74.             'code' => 1,
  75.             'message' => 'waiting',
  76.         ];
  77.     }
  78.     /**
  79.      * 创建目录
  80.      */
  81.     private function touchDir(){
  82.         if(!file_exists($this->filepath)){
  83.             return mkdir($this->filepath);
  84.         }
  85.     }
  86. }
复制代码


调用上传类

  1. $tmpName = $_FILES['file']['tmp_name'];
  2. $blobNum = $_POST['blob_num'];
  3. $totalBlobNum = $_POST['total_blob_num'];
  4. $fileName = $_POST['file_name'];
  5. $upload = new Upload($tmpName, $blobNum, $totalBlobNum, $fileName);
  6. $data = $upload->uploadReturn();
  7. header('Content-type: application/json');
  8. return json_encode($data);
复制代码


根据如上步骤就可以实现将文件分成若干块进行上传功能

到此这篇关于PHP+JS实现文件分块上传的示例代码的文章就介绍到这了,更多相关PHP JS文件分块上传内容请搜索站内更多内容!

您需要登录后才可以回帖 登录 | 会员注册

本版积分规则

锦尚中国源码论坛

聚合标签|锦尚中国,为中国网站设计添动力 ( 鲁ICP备09033200号 ) |网站地图

GMT+8, 2024-10-15 05:41 , Processed in 0.161594 second(s), 25 queries .

带宽由 锦尚数据 提供 专业的数据中心

© 锦尚中国源码论坛 52jscn Inc. 非法入侵必将受到法律制裁 法律顾问:IT法律网 & 褚福省律师 锦尚爱心 版权申诉 版权与免责声明