Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you use Dropzone.js with chunked file uploads (PHP only)?

I can find plenty of documentation on how to use the chunked file upload with various API's and libraries, but I am unable to find how to use Dropzone.js chunked file upload with just plain PHP.

The documentation is very minimal. I cannot add any libraries or API's other than jQuery on the client side (JavaScript).

My question is how do you use Dropzone.js new chunked file upload feature with PHP only on the server side. (Client side code is appreciated for setup).

Here is the code I've attempted so far: Client side .js file:

    var myDropzone = new Dropzone("div#formDiv", 
    {
        url: "uploadform.php",
        params: function (files, xhr, chunk)
        {
            if (chunk)
            {
                return
                {
                    dzUuid=chunk.file.upload.uuid,
                    dzChunkIndex=chunk.index,
                    dzTotalFileSize=chunk.file.size,
                    dzCurrentChunkSize=chunk.dataBlock.data.size,
                    dzTotalChunkCount=chunk.file.upload.totalChunkCount,
                    dzChunkByteOffset=chunk.index * this.options.chunkSize,
                    dzChunkSize=this.options.chunkSize,
                    dzFilename=chunk.file.name;
                };
            }
        },
        method: "post",
        timeout: 600000,
        maxFileSize: 1024,
        parallelUploads: 1,
        chunking: true,
        forceChunking: true,
        chunkSize: 1000000,
        parallelChunkUploads: true,
        retryChunks: true,
        retryChunksLimit: 3,
        chunksUploaded: function (file, done)
        {
            // All chunks have uploaded successfully

        },
        error: function (msg)
        {
            alert(msg.responseText);
        }
});

Here is the PHP (server):

foreach ($_POST as $key => $value)
{
    _log('key:' . $key . '; Value:' . $value);
}

The above code shows nothing (_log() just echoes it to the screen and logs it in a text file).

I looked at the send/receive headers and it only sends one call to the server.

I've verified that the file drag/drop zone is setup correctly by Dropzone.js using the developer tools console in the browser.

Edit: Here is the documentation for chunked uploads: https://gitlab.com/meno/dropzone/wikis/faq#chunked-uploads

Chunked uploads

Dropzone offers the possibility to upload files in chunks. The relevant configuration options for this feature are:

chunking which should be set to true

forceChunking, if true, will always send a file in chunks, even if it is only one chunk

chunkSize in bytes

parallelChunkUploads, if true, the chunks will be uploaded simultaneously

retryChunks, if true, the library will retry to upload a chunk if it fails

retryChunksLimit defaults to 3

Then there are two important callbacks. The first one is: params which can be a function, that receives files, xhr and chunk as the first argument. If chunking is enabled, you know that files only contains that one file, and chunk is the object holding all the information about the current chunk. Example:

var chunk = {
  file: file,
  index: 0,
  status: Dropzone.UPLOADING,
  progress: 0.4
}

See the documentation for that parameter for more information or look at the source code for the default implementation.

The second important callback is chunksUploaded, which gets the file that finished uploading and the done function as second argument. Do whatever you need to do in that function, to tell the server that the file finished uploading and invoke the done() function when ready.

like image 913
Lokiare Avatar asked May 17 '18 17:05

Lokiare


1 Answers

I found that I had a number of problems. One was that I wasn't using the most recent version of Dropzone.js.

Another was that I wasn't checking $_FILE and $_POST for the variables and file parts.

Once I got those fixed, I changed the JavaScript to:

    var myDropzone = new Dropzone("div#formDiv", 
    {
        url: "uploadform.php",
        method: "post",
        timeout: 180000,
        maxFileSize: 1024,
        parallelUploads: 1,
        chunking: true,
        forceChunking: true,
        chunkSize: 256000,
        parallelChunkUploads: true,
        retryChunks: true,
        retryChunksLimit: 3,
    };

By removing the params function, I get the default values. These values include the chunk index and the maximum number of chunks.

From there I was able to get the chunked files in the PHP script using:

$_FILE['file']['name']
$_FILE['file']['tmp_name']
$_POST['dzchunkindex']
$_POST['dztotalchunkcount']

After that it was just a matter of checking in the PHP script for all the file parts being uploaded and then re-assembling them which is handled in many tutorials that are easy to find on the internet.

like image 50
Lokiare Avatar answered Nov 18 '22 05:11

Lokiare