文章詳情頁
PHP+JS實現文件分塊上傳的示例代碼
瀏覽:87日期:2022-06-05 18:43:59
目錄
- 一、分塊上傳流程
- 二、實現代碼
- HTML
- JS
- PHP
我們在上傳大文件時,可能會由于服務器的原因導致文件上傳失敗,文件過大時由于服務器的配置或響應事件過長導致上傳文件失敗,這時候我們可以將一個大的文件分為若干塊,然后分批次上傳到服務端,當所有文件塊上傳完成后再由服務器將各個文件塊整合成我們上傳的文件
一、分塊上傳流程
1:由前端js將上傳的文件信息進行切割成若干塊,然后循環將若干塊的文件塊上傳到服務端
2:服務端接收到文件塊信息后保存起來,當所有文件塊上傳完畢后,將所有上傳的文件塊整合成文件并保存起來
二、實現代碼
HTML
<input type="file" id="file"> <input type="button" id="upload" value="上傳"> <input type="button" id="stop" value="停止"> <input type="button" id="restart" value="繼續上傳"> 上傳進度:<span id="progress"></span>
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 < file.size && is_stop == 0) { blob = cutFile(file); uploadFile(blob, file); blob_num += 1; } else { //所有文件塊上傳完成 } }, 1000); } xhr.send(form_data); //每次文件塊上傳后,清空上傳信息 form_data = ""; } }
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; $i<= $this->totalBlobNum; $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; $i<= $this->totalBlobNum; $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文件分塊上傳內容請搜索以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持!
標簽:
PHP
排行榜