Ausführliche Erklärung des geteilten PHP-Uploads großer Dateien

墨辰丷
Freigeben: 2023-03-26 14:44:01
Original
1750 Leute haben es durchsucht

Dieser Artikel stellt hauptsächlich den PHP-Upload großer Dateien und den PHP-Split-Upload im Detail vor, der einen gewissen Referenzwert hat.

Warum kann der Server keine großen Dateien hochladen? Es hängt mit mehreren Konfigurationen in php.ini zusammen

upload_max_filesize = 2M //PHP最大能接受的文件大小
post_max_size = 8M //PHP能收到的最大POST值'
memory_limit = 128M //内存上限
max_execution_time = 30 //最大执行时间
Nach dem Login kopieren

Natürlich können Sie die oben genannten Werte nicht einfach und grob erhöhen, da sonst die Speicherressourcen des Servers erschöpft sind früher oder später ein Problem.

Lösung

Glücklicherweise hat HTML5 eine neue FILE-API eröffnet, die auch Binärobjekte direkt im Browser bedienen kann Seite Um das Schneiden von Dateien zu erreichen, müssen Sie gemäß der bisherigen Praxis die Flash-Lösung verwenden, deren Implementierung sehr schwierig ist.

JS-Idee
1. Hören Sie sich das Onchange-Ereignis der Upload-Schaltfläche an
2. Holen Sie sich das FILE-Objekt der Datei und hängen Sie es an das FORMDATA-Objekt
4. Senden Sie das FORMDATA-Objekt über AJAX
5. Wiederholen Sie die Schritte 3 und 4, bis die Datei gesendet wird.

PHP-Ideen

1. Erstellen Sie einen Upload-Ordner
2. Verschieben Sie Dateien aus dem Upload-Temporärverzeichnis in den Upload-Ordner
3. Führen Sie die Dateisynthese durch
4. Löschen Sie den Ordner
5. Kehren Sie zum hochgeladenen Dateipfad zurück

DEMO-Code

Front-End-Teilecode


<!doctype html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport"
     content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <style>
    #progress{
      width: 300px;
      height: 20px;
      background-color:#f7f7f7;
      box-shadow:inset 0 1px 2px rgba(0,0,0,0.1);
      border-radius:4px;
      background-image:linear-gradient(to bottom,#f5f5f5,#f9f9f9);
    }

    #finish{
      background-color: #149bdf;
      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);
      background-size:40px 40px;
      height: 100%;
    }
    form{
      margin-top: 50px;
    }
  </style>
</head>
<body>
<p id="progress">
  <p id="finish" style="width: 0%;" progress="0"></p>
</p>
<form action="./upload.php">
  <input type="file" name="file" id="file">
  <input type="button" value="停止" id="stop">
</form>
<script>
  var fileForm = document.getElementById("file");
  var stopBtn = document.getElementById(&#39;stop&#39;);
  var upload = new Upload();

  fileForm.onchange = function(){
    upload.addFileAndSend(this);
  }

  stopBtn.onclick = function(){
    this.value = "停止中";
    upload.stop();
    this.value = "已停止";
  }

  function Upload(){
    var xhr = new XMLHttpRequest();
    var form_data = new FormData();
    const LENGTH = 1024 * 1024;
    var start = 0;
    var end = start + LENGTH;
    var blob;
    var blob_num = 1;
    var is_stop = 0
    //对外方法,传入文件对象
    this.addFileAndSend = function(that){
      var file = that.files[0];
      blob = cutFile(file);
      sendFile(blob,file);
      blob_num += 1;
    }
    //停止文件上传
    this.stop = function(){
      xhr.abort();
      is_stop = 1;
    }
    //切割文件
    function cutFile(file){
      var file_blob = file.slice(start,end);
      start = end;
      end = start + LENGTH;
      return file_blob;
    };
    //发送文件
    function sendFile(blob,file){
      var total_blob_num = Math.ceil(file.size / LENGTH);
      form_data.append(&#39;file&#39;,blob);
      form_data.append(&#39;blob_num&#39;,blob_num);
      form_data.append(&#39;total_blob_num&#39;,total_blob_num);
      form_data.append(&#39;file_name&#39;,file.name);

      xhr.open(&#39;POST&#39;,&#39;./upload.php&#39;,false);
      xhr.onreadystatechange = function () {
        var progress;
        var progressObj = document.getElementById(&#39;finish&#39;);
        if(total_blob_num == 1){
          progress = &#39;100%&#39;;
        }else{
          progress = Math.min(100,(blob_num/total_blob_num)* 100 ) +&#39;%&#39;;
        }
        progressObj.style.width = progress;
        var t = setTimeout(function(){
          if(start < file.size && is_stop === 0){
            blob = cutFile(file);
            sendFile(blob,file);
            blob_num += 1;
          }else{
            setTimeout(t);
          }
        },1000);
      }
      xhr.send(form_data);
    }
  }

</script>
</body>
</html>
Nach dem Login kopieren

PHP-Teilecode

<?php
class Upload{
  private $filepath = &#39;./upload&#39;; //上传目录
  private $tmpPath; //PHP文件临时目录
  private $blobNum; //第几个文件块
  private $totalBlobNum; //文件块总数
  private $fileName; //文件名

  public function __construct($tmpPath,$blobNum,$totalBlobNum,$fileName){
    $this->tmpPath = $tmpPath;
    $this->blobNum = $blobNum;
    $this->totalBlobNum = $totalBlobNum;
    $this->fileName = $fileName;
    
    $this->moveFile();
    $this->fileMerge();
  }
  
  //判断是否是最后一块,如果是则进行文件合成并且删除文件块
  private function fileMerge(){
    if($this->blobNum == $this->totalBlobNum){
      $blob = &#39;&#39;;
      for($i=1; $i<= $this->totalBlobNum; $i++){
        $blob .= file_get_contents($this->filepath.&#39;/&#39;. $this->fileName.&#39;__&#39;.$i);
      }
      file_put_contents($this->filepath.&#39;/&#39;. $this->fileName,$blob);
      $this->deleteFileBlob();
    }
  }
  
  //删除文件块
  private function deleteFileBlob(){
    for($i=1; $i<= $this->totalBlobNum; $i++){
      @unlink($this->filepath.&#39;/&#39;. $this->fileName.&#39;__&#39;.$i);
    }
  }
  
  //移动文件
  private function moveFile(){
    $this->touchDir();
    $filename = $this->filepath.&#39;/&#39;. $this->fileName.&#39;__&#39;.$this->blobNum;
    move_uploaded_file($this->tmpPath,$filename);
  }
  
  //API返回数据
  public function apiReturn(){
    if($this->blobNum == $this->totalBlobNum){
        if(file_exists($this->filepath.&#39;/&#39;. $this->fileName)){
          $data[&#39;code&#39;] = 2;
          $data[&#39;msg&#39;] = &#39;success&#39;;
          $data[&#39;file_path&#39;] = &#39;http://&#39;.$_SERVER[&#39;HTTP_HOST&#39;].dirname($_SERVER[&#39;DOCUMENT_URI&#39;]).str_replace(&#39;.&#39;,&#39;&#39;,$this->filepath).&#39;/&#39;. $this->fileName;
        }
    }else{
        if(file_exists($this->filepath.&#39;/&#39;. $this->fileName.&#39;__&#39;.$this->blobNum)){
          $data[&#39;code&#39;] = 1;
          $data[&#39;msg&#39;] = &#39;waiting for all&#39;;
          $data[&#39;file_path&#39;] = &#39;&#39;;
        }
    }
    header(&#39;Content-type: application/json&#39;);
    echo json_encode($data);
  }
  
  //建立上传文件夹
  private function touchDir(){
    if(!file_exists($this->filepath)){
      return mkdir($this->filepath);
    }
  }
}

//实例化并获取系统变量传参
$upload = new Upload($_FILES[&#39;file&#39;][&#39;tmp_name&#39;],$_POST[&#39;blob_num&#39;],$_POST[&#39;total_blob_num&#39;],$_POST[&#39;file_name&#39;]);
//调用方法,返回结果
$upload->apiReturn();
Nach dem Login kopieren

Verwandte Empfehlungen:


HTML5-Technologie zum Hochladen großer Dateien

So verwenden Sie Ajax, um die Funktion zum Hochladen großer Dateien zu implementieren

JS und WebService Datei-Upload-Codefreigabe

Das obige ist der detaillierte Inhalt vonAusführliche Erklärung des geteilten PHP-Uploads großer Dateien. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Verwandte Etiketten:
Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage