Upload Files in Chunk using PHP and JavaScript

Often, we need users to upload files via a webpage. There’s not much challenge if the file is a simple text file or a small image file. The real challenge arises when there’s a big files (zip or videos or any other).

In this article, we will learn to upload file in small chunks. The major advantage of uploading in chunk is that the script doesn’t reach maximum execution time.

Lets dive into the steps to achieve this :

Folder Structure

1. Download Plupload File Uploader

You can download the latest version of Plupload: Multi-runtime File-Uploader from here : https://www.plupload.com/download

2. Create File Upload Form

index.php

<!DOCTYYPE html>
<html>
  <head>
    <title>Chunking Upload Demo</title>
    <script src="plupload/js/plupload.full.min.js"></script>
    <script>
      window.addEventListener("load", function () {
        var path = "plupload/js/`";
        var uploader = new plupload.Uploader({
          browse_button: 'pickfiles',
          container: document.getElementById('container'),
          url: 'upload.php',
          chunk_size: '1000kb',
          max_retries: 2,
          filters: {
            max_file_size: '30mb',
            mime_types: [{title: "Video", extensions: "mp4,3gp,mov"}]
          },
          init: {
            PostInit: function () {
              document.getElementById('filelist').innerHTML = '';
            },
            FilesAdded: function (up, files) {
              plupload.each(files, function (file) {
                document.getElementById('filelist').innerHTML += '<div id="' + file.id + '">' + file.name + ' (' + plupload.formatSize(file.size) + ') <b></b></div>';
              });
              uploader.start();
            },
            UploadProgress: function (up, file) {
              document.getElementById(file.id).getElementsByTagName('b')[0].innerHTML = '<span>' + file.percent + "%</span>";
            },
            Error: function (up, err) {
              // DO YOUR ERROR HANDLING!
              console.log(err);
            }
          }
        });
        uploader.init();
      });
    </script>
  </head>
  <body>
    <div id="container">
      <span id="pickfiles">[Upload files]</span>
    </div>
    <div id="filelist">Your browser doesn't have Flash, Silverlight or HTML5 support.</div>
  </body>
</html>

3. PHP Script to handle file upload

upload.php

<?php
// RESPONSE FUNCTION
function verbose($ok=1,$info=""){
  // THROW A 400 ERROR ON FAILURE
  if ($ok==0) { http_response_code(400); }
  die(json_encode(["ok"=>$ok, "info"=>$info]));
}

// INVALID UPLOAD
if (empty($_FILES) || $_FILES['file']['error']) {
  verbose(0, "Failed to move uploaded file.");
}

// THE UPLOAD DESITINATION - CHANGE THIS TO YOUR OWN
$filePath = __DIR__ . DIRECTORY_SEPARATOR . "uploads";
if (!file_exists($filePath)) { 
  if (!mkdir($filePath, 0777, true)) {
    verbose(0, "Failed to create $filePath");
  }
}
$fileName = isset($_REQUEST["name"]) ? $_REQUEST["name"] : $_FILES["file"]["name"];
$filePath = $filePath . DIRECTORY_SEPARATOR . $fileName;

// DEAL WITH CHUNKS
$chunk = isset($_REQUEST["chunk"]) ? intval($_REQUEST["chunk"]) : 0;
$chunks = isset($_REQUEST["chunks"]) ? intval($_REQUEST["chunks"]) : 0;
$out = @fopen("{$filePath}.part", $chunk == 0 ? "wb" : "ab");
if ($out) {
  $in = @fopen($_FILES['file']['tmp_name'], "rb");
  if ($in) {
    while ($buff = fread($in, 4096)) { fwrite($out, $buff); }
  } else {
    verbose(0, "Failed to open input stream");
  }
  @fclose($in);
  @fclose($out);
  @unlink($_FILES['file']['tmp_name']);
} else {
  verbose(0, "Failed to open output stream");
}

// CHECK IF FILE HAS BEEN UPLOADED
if (!$chunks || $chunk == $chunks - 1) {
  rename("{$filePath}.part", $filePath);
}
verbose(1, "Upload OK");
?>

Follow this video for complete guidance :

Recommended For You

About the Author: Ritesh Ghimire

Ritesh is a Computer Engineer, Web Developer and an active cricket follower.