Chunked file uploads with Laravel 9

10-Apr-2023

.

Admin

Chunked file uploads with Laravel 9

Hi friends,

Today, I am going to show you simple example of how to chunk upload file using Javascript in laravel 9?. In this tutorial you can find how to chunk upload file on folder by using Javascript in Laravel 9. In this article we explain how to chunk upload file in laravel 9 using Javascript Example. This example explain you Laravel 9 – Javascript chunk file upload example tutorial step by step. More then times we need to save the file data with Javascript request in laravel 9 app without page reload and refresh. In this laravel 9 Javascript chunk file upload tutorial i will show you how to upload chunk file using javascript request. Also we will see how to validate the file before uploading it into server.

If you know laravel javascript uploading chunk file in laravel using javascript and save in database it too easy. Call the store method with the path at which you wish to store the uploaded chunk file.

We can upload chunk file using Javascript request in laravel 9 very easily. Let's start our laravel 9 ajax file upload tutorial from scratch.

Step 1: Download Laravel


Let us begin the tutorial by installing a new laravel application. if you have already created the project, then skip following step.

composer create-project laravel/laravel example-app

Step 2: Download Playpload

You can download the playpload. Extract the zip file and place the project named larval-file-upload in the public path.

https://www.plupload.com/download

Step 3: Add Migration and Model

Here, we will create migration for "chunk_files" table, let's run bellow command and update code.

php artisan make:migration create_chunk_files_table

database/migrations/2022_03_23_124255_create_chunk_files_table.php

<?php

use Illuminate\Database\Migrations\Migration;

use Illuminate\Database\Schema\Blueprint;

use Illuminate\Support\Facades\Schema;

return new class extends Migration

{

/**

* Run the migrations.

*

* @return void

*/

public function up()

{

Schema::create('chunk_files', function (Blueprint $table) {

$table->id();

$table->string('file');

$table->timestamps();

});

}

/**

* Reverse the migrations.

*

* @return void

*/

public function down()

{

Schema::dropIfExists('chunk_files');

}

};

Next, run create new migration using laravel migration command as bellow:

php artisan migrate

Now we will create File model by using following command:

php artisan make:model ChunkFile

app/Models/ChunkFile.php

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;

use Illuminate\Database\Eloquent\Model;

class ChunkFile extends Model

{

use HasFactory;

protected $fillable = [

'file'

];

}

Step 4: Add Controller

In this step, we will create a new FileUploadController; in this file, we will add two method create() and chunkStore() for render view and store files into folder and database logic.

Let's create ChunkFileController by following command:

php artisan make:controller ChunkFileController

next, let's update the following code to Controller File.

app/Http/Controllers/ChunkFileController.php

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

use App\Models\ChunkFile;

class ChunkFileController extends Controller

{

/**

* Write code on Method

*

* @return response()

*/

public function create()

{

return view('chunkUpload');

}

/**

* Write code on Method

*

* @return response()

*/

public function chunkStore(Request $request)

{

$_REQUEST["name"];

$input = $request->all();

// THE UPLOAD DESITINATION - CHANGE THIS TO YOUR OWN

$filePath = storage_path('app/public/upload/testChunk');

if (!file_exists($filePath)) {

if (!mkdir($filePath, 0777, true)) {

return response()->json(["ok"=>0, "info"=>"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 {

return response()->json(["ok"=>0, "info"=>'Failed to open input stream']);

}

fclose($in);

fclose($out);

unlink($_FILES['file']['tmp_name']);

}

// CHECK IF FILE HAS BEEN UPLOADED

if (!$chunks || $chunk == $chunks - 1) {

rename("{$filePath}.part", $filePath);

$array = ['file' => $fileName];

ChunkFile::create($array);

}

$info = "Upload OK";

$ok =1;

return response()->json(["ok"=>$ok, "info"=>$info]);

}

}

Store Files in Storage Folder:

$filePath = storage_path('app/public/upload/testChunk');

Step 5: Add Routes

Furthermore, open routes/web.php file and add the routes to manage GET and POST requests for render view and store file logic.

routes/web.php

<?php

use Illuminate\Support\Facades\Route;

use App\Http\Controllers\ChunkFileController;

/*

|--------------------------------------------------------------------------

| Web Routes

|--------------------------------------------------------------------------

|

| Here is where you can register web routes for your application. These

| routes are loaded by the RouteServiceProvider within a group which

| contains the "web" middleware group. Now create something great!

|

*/

Route::get('file-upload',[ChunkFileController::class,'create']) ;

Route::post('chunk',[ChunkFileController::class,'chunkStore'])->name('chunk.store');

Step 6: Add Blade File

At last step we need to create chunkUpload.blade.php file and in this file we will create form with file input Javascript code. So copy bellow and put on that file.

resources/views/chunkUpload.blade.php

<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="utf-8">

<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

<title>Chunk File Upload in Laravel</title>

<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">

</head>

<body>

<div class="container mt-5">

<div class="row">

<div class="col-md-12">

<div class="card w-50 m-auto">

<div class="card-header bg-info text-white">

<h4>Chunk File Upload in Laravel</h4>

</div>

<div class="card-body">

<div class="form-group" id="file-input">

<input type="file" id="pickfiles" class="form-control">

<div id="filelist"></div>

</div>

</div>

</div>

</div>

</div>

</div>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>

<script src="{{ asset('/plupload/js/plupload.full.min.js') }}"></script>

<script type="text/javascript">

$(document).ready(function () {

var path = "{{ asset('/plupload/js/') }}";

var uploader = new plupload.Uploader({

browse_button: 'pickfiles',

container: document.getElementById('file-input'),

url: '{{ route("chunk.store") }}',

chunk_size: '10kb', // 1 MB

max_retries: 2,

filters: {

max_file_size: '200mb'

},

multipart_params : {

// Extra Parameter

"_token" : "{{ csrf_token() }}"

},

init: {

PostInit: function () {

document.getElementById('filelist').innerHTML = '';

},

FilesAdded: function (up, files) {

plupload.each(files, function (file) {

console.log('FilesAdded');

console.log(file);

document.getElementById('filelist').innerHTML += '<div id="' + file.id + '">' + file.name + ' (' + plupload.formatSize(file.size) + ') <b></b></div>';

});

uploader.start();

},

UploadProgress: function (up, file) {

console.log('UploadProgress');

console.log(file);

document.getElementById(file.id).getElementsByTagName('b')[0].innerHTML = '<span>' + file.percent + "%</span>";

},

FileUploaded: function(up, file, result){

console.log('FileUploaded');

console.log(file);

console.log(JSON.parse(result.response));

responseResult = JSON.parse(result.response);

if (responseResult.ok==0) {

toastr.error(responseResult.info, 'Error Alert', {timeOut: 5000});

}

if (result.status != 200) {

toastr.error('Your File Uploaded Not Successfully!!', 'Error Alert', {timeOut: 5000});

}

if (responseResult.ok==1 && result.status == 200) {

toastr.success('Your File Uploaded Successfully!!', 'Success Alert', {timeOut: 5000});

}

},

UploadComplete: function(up, file){

// toastr.success('Your File Uploaded Successfully!!', 'Success Alert', {timeOut: 5000});

},

Error: function (up, err) {

// DO YOUR ERROR HANDLING!

toastr.error('Your File Uploaded Not Successfully!!', 'Error Alert', {timeOut: 5000});

console.log(err);

}

}

});

uploader.init();

});

</script>

</body>

</html>

Run Laravel App:

All steps have been done, now you have to type the given command and hit enter to run the laravel app:

php artisan serve

Now, you have to open web browser, type the given URL and view the app output:

http://localhost:8000/file-upload

Output:

It will help you...

#Laravel 9