[PHP] 大文件分片上传 →→→→→进入此内容的聊天室

来自 , 2019-10-19, 写在 PHP, 查看 138 次.
URL http://www.code666.cn/view/e846fb8a
  1. <!doctype html>
  2. <html lang="en">
  3. <head>
  4.     <meta charset="UTF-8">
  5.     <meta name="viewport"
  6.         content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
  7.     <meta http-equiv="X-UA-Compatible" content="ie=edge">
  8.     <title>Document</title>
  9.     <style>
  10.         #progress{
  11.             width: 300px;
  12.             height: 20px;
  13.             background-color:#f7f7f7;
  14.             box-shadow:inset 0 1px 2px rgba(0,0,0,0.1);
  15.             border-radius:4px;
  16.             background-image:linear-gradient(to bottom,#f5f5f5,#f9f9f9);
  17.         }
  18.      
  19.         #finish{
  20.             background-color: #149bdf;
  21.             background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);
  22.             background-size:40px 40px;
  23.             height: 100%;
  24.         }
  25.         form{
  26.             margin-top: 50px;
  27.         }
  28.       </style>
  29. </head>
  30. <body>
  31. <div id="progress">
  32.     <div id="finish" style="width: 0%;" progress="0"></div>
  33. </div>
  34. <form action="./upload.php">
  35.     <input type="file" name="file" id="file">
  36.     <input type="button" value="停止" id="stop">
  37. </form>
  38. <script>
  39.     var fileForm = document.getElementById("file");
  40.     var stopBtn = document.getElementById('stop');
  41.     var upload = new Upload();
  42.  
  43.     fileForm.onchange = function(){
  44.         // alert(this.files[0].name)
  45.         upload.addFileAndSend(this);
  46.     }
  47.  
  48.     stopBtn.onclick = function(){
  49.         this.value = "停止中";
  50.         upload.stop();
  51.         this.value = "已停止";
  52.     }
  53.  
  54.     function Upload(){
  55.         var xhr = new XMLHttpRequest();
  56.         var form_data = new FormData();
  57.         const LENGTH = 1024 * 1024;
  58.         var start = 0;
  59.         var end = start + LENGTH;
  60.         var blob;
  61.         var blob_num = 1;
  62.         var is_stop = 0
  63.         //对外方法,传入文件对象
  64.         this.addFileAndSend = function(that){
  65.             var file = that.files[0];
  66.             blob = cutFile(file);
  67.             sendFile(blob,file);
  68.             blob_num += 1;
  69.         }
  70.         //停止文件上传
  71.         this.stop = function(){
  72.             xhr.abort();
  73.             is_stop = 1;
  74.         }
  75.         //切割文件
  76.         function cutFile(file){
  77.             var file_blob = file.slice(start,end);
  78.             start = end;
  79.             end = start + LENGTH;
  80.             return file_blob;
  81.         };
  82.         //发送文件
  83.         function sendFile(blob,file){
  84.             var total_blob_num = Math.ceil(file.size / LENGTH);
  85.             form_data.append('file',blob);
  86.             form_data.append('blob_num',blob_num);
  87.             form_data.append('total_blob_num',total_blob_num);
  88.             form_data.append('file_name',file.name);
  89.      
  90.             xhr.open('POST','./upload.php',false);
  91.             xhr.onreadystatechange = function () {
  92.                 var progress;
  93.                 var progressObj = document.getElementById('finish');
  94.                 if(total_blob_num == 1){
  95.                     progress = '100%';
  96.                 }else{
  97.                     progress = Math.min(100,(blob_num/total_blob_num)* 100 ) +'%';
  98.                 }
  99.                 progressObj.style.width = progress;
  100.                 var t = setTimeout(function(){
  101.                     if(start < file.size && is_stop === 0){
  102.                         blob = cutFile(file);
  103.                         sendFile(blob,file);
  104.                         blob_num += 1;
  105.                     }else{
  106.                         // setTimeout(t);
  107.                         clearTimeout(t);
  108.                     }
  109.                 },1000);
  110.             }
  111.             xhr.send(form_data);
  112.         }
  113.     }
  114. </script>
  115. </body>
  116. </html>
  117.  
  118.  
  119. <?php
  120. class Upload{
  121.     private $filepath = './upload'; //上传目录
  122.     private $tmpPath; //PHP文件临时目录
  123.     private $blobNum; //第几个文件块
  124.     private $totalBlobNum; //文件块总数
  125.     private $fileName; //文件名
  126.  
  127.     public function __construct($tmpPath,$blobNum,$totalBlobNum,$fileName){
  128.         $this->tmpPath = $tmpPath;
  129.         $this->blobNum = $blobNum;
  130.         $this->totalBlobNum = $totalBlobNum;
  131.         $this->fileName = $fileName;
  132.      
  133.         $this->moveFile();
  134.         $this->fileMerge();
  135.     }
  136.    
  137.     //判断是否是最后一块,如果是则进行文件合成并且删除文件块
  138.     private function fileMerge(){
  139.         if($this->blobNum == $this->totalBlobNum){
  140.             $blob = '';
  141.             for($i=1; $i<= $this->totalBlobNum; $i++){
  142.                 $blob .= file_get_contents($this->filepath.'/'. $this->fileName.'__'.$i);
  143.             }
  144.             file_put_contents($this->filepath.'/'. $this->fileName,$blob);
  145.             $this->deleteFileBlob();
  146.         }
  147.     }
  148.    
  149.     //删除文件块
  150.     private function deleteFileBlob(){
  151.         for($i=1; $i<= $this->totalBlobNum; $i++){
  152.             @unlink($this->filepath.'/'. $this->fileName.'__'.$i);
  153.         }
  154.     }
  155.    
  156.     //移动文件
  157.     private function moveFile(){
  158.         $this->touchDir();
  159.         $filename = $this->filepath.'/'. $this->fileName.'__'.$this->blobNum;
  160.         move_uploaded_file($this->tmpPath,$filename);
  161.     }
  162.    
  163.     //API返回数据
  164.     public function apiReturn(){
  165.         if($this->blobNum == $this->totalBlobNum){
  166.             if(file_exists($this->filepath.'/'. $this->fileName)){
  167.                 $data['code'] = 2;
  168.                 $data['msg'] = 'success';
  169.                 $data['file_path'] = 'http://'.$_SERVER['HTTP_HOST'].dirname($_SERVER['DOCUMENT_URI']).str_replace('.','',$this->filepath).'/'. $this->fileName;
  170.             }
  171.         }else{
  172.             if(file_exists($this->filepath.'/'. $this->fileName.'__'.$this->blobNum)){
  173.                 $data['code'] = 1;
  174.                 $data['msg'] = 'waiting for all';
  175.                 $data['file_path'] = '';
  176.             }
  177.         }
  178.         header('Content-type: application/json');
  179.         echo json_encode($data);
  180.     }
  181.    
  182.     //建立上传文件夹
  183.     private function touchDir(){
  184.         if(!file_exists($this->filepath)){
  185.             return mkdir($this->filepath);
  186.         }
  187.     }
  188. }
  189.  
  190. //实例化并获取系统变量传参
  191. $upload = new Upload($_FILES['file']['tmp_name'],$_POST['blob_num'],$_POST['total_blob_num'],$_POST['file_name']);
  192. //调用方法,返回结果
  193. $upload->apiReturn();
  194.  

回复 "大文件分片上传"

这儿你可以回复上面这条便签

captcha