How to Upload Multiple Files in Laravel 12

How to Upload Multiple Files in Laravel 12

 How to Upload Multiple Files in Laravel 12

Iutorial, we will learn how to upload multiple files in Laravel 12, store file information in the MySQL database, and use Laravel's logging system with session-based file group naming.

Step 1: Create a Migration for the uploads Table

Run the migration command:

php artisan make:migration create_uploads_table

Then define your table structure in the generated migration:

// database/migrations/xxxx_xx_xx_create_uploads_table.php use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; return new class extends Migration { public function up(): void { Schema::create('uploads', function (Blueprint $table) { $table->id(); $table->string('filename'); $table->string('upload_name')->nullable(); $table->timestamp('uploaded_at')->nullable(); $table->timestamps(); }); } public function down(): void { Schema::dropIfExists('uploads'); } };

Then run:

php artisan migrate

Step 2: Create the Upload Model

php artisan make:model Upload

Edit the model to allow mass assignment:

// app/Models/Upload.php namespace App\Models; use Illuminate\Database\Eloquent\Model; class Upload extends Model { protected $fillable = ['filename', 'upload_name', 'uploaded_at']; }

Step 3: Create the Upload Controller

php artisan make:controller FormController

Step 4: Define Routes

In routes/web.php:

// ------------------------- Form Upload ----------------------------// Route::controller(FormController::class)->group(function () { Route::middleware('auth')->group(function () { Route::get('form/upload/page', 'index')->name('form.upload.page'); Route::post('form/upload/save', 'storeFileUpload')->name('form.upload.save'); }); });

Step 5: Create the Blade Upload Form

<!-- resources/views/upload.blade.php --> @extends('layouts.master') @section('style') <style> .file-row { display: flex; justify-content: space-between; align-items: center; margin-bottom: 8px; padding-bottom: 6px; border-bottom: 1px solid #eee; } .file-name { flex: 1; color: #444; font-size: 14px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .icon { display: inline-block; font-size: 1.2em; line-height: 1; margin-right: 0.5em; } .icon.success { color: green; padding-left: 8px; } .icon.remove { color: red; cursor: pointer; } </style> @endsection @section('content') <div class="row"> <div class="col-lg-12 col-md-8 col-sm-12 mx-auto"> <div class="d-flex justify-content-between align-items-center mb-3"> <div class="fw-bold py-2">Page Form</div> <div class="p-2"> Page Form - <a href="{{ route('home') }}" class="text-decoration-none fw-semibold">Dashboard</a> </div> </div> <div class="card p-3 shadow-sm"> <div class="container py-3"> <form id="uploadForm" action="{{ route('form/upload/save') }}" method="POST" enctype="multipart/form-data"> @csrf <div class="mb-3 row"> <label for="fileupload" class="form-label">Upload Files</label> <div class="col-sm-3"> <input type="file" class="form-control" id="fileupload" name="fileupload[]" multiple> </div> </div> <div class="mb-3 row"> <div class="col-12"> <div id="file-list"></div> </div> </div> <div class="mb-3 row"> <div class="col-sm-3"> <button type="submit" class="btn btn-primary">Submit</button> </div> </div> </form> </div> </div> </div> </div> @endsection @section('script') <script> const $input = $('#fileupload'); const $list = $('#file-list'); const files = []; const formatSize = bytes => bytes < 1024 ? `${bytes} B` : `${(bytes / 1024).toFixed(1)} Kb`; $input.on('change', function () { Array.from(this.files).forEach(file => { const exists = files.some(f => f.name === file.name && f.size === file.size); if (!exists) { files.push(file); } }); this.value = null; renderFileList(); }); $list.on('click', '.remove', e => { const index = $(e.target).data('idx'); files.splice(index, 1); renderFileList(); }); function renderFileList() { const dataTransfer = new DataTransfer(); $list.empty(); files.forEach((file, index) => { dataTransfer.items.add(file); $list.append(` <div class="file-row"> <span class="file-name">${file.name}</span> <span class="file-size">${formatSize(file.size)}</span> <span class="icon success">✓</span> <span class="icon remove" data-idx="${index}">✕</span> </div> `); }); $input[0].files = dataTransfer.files; } </script> @endsection

Step 6: Implement the Store Logic

// app/Http/Controllers/FormController.php <?php namespace App\Http\Controllers; use Illuminate\Support\Facades\Storage; use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Log; use Illuminate\Http\Request; use App\Models\Upload; use Carbon\Carbon; class FormController extends Controller { /** * Display the file upload form. * * @return \Illuminate\View\View */ public function index() { return view('form.upload'); } /** * Handle file upload and save to the database. * * @param \Illuminate\Http\Request $request * @return \Illuminate\Http\RedirectResponse */ public function storeFileUpload(Request $request) { // Validate the uploaded files $request->validate([ 'fileupload.*' => 'required|file|mimes:jpg,jpeg,png,pdf,docx|max:2048' ]); try { // Check if files are present in the request if ($request->hasFile('fileupload')) { foreach ($request->file('fileupload') as $file) { // Create a unique filename with timestamp to avoid filename conflicts $filename = time() . '_' . $file->getClientOriginalName(); // Store the file in the 'uploads' directory within the public disk $path = $file->storeAs('uploads', $filename, 'public'); // Save file info to the database Upload::create([ 'filename' => $filename, 'upload_name' => Auth::user()->name, 'uploaded_at' => Carbon::now() ]); } } return back()->with('success', 'Files uploaded and saved successfully.'); } catch (\Exception $e) { // Log any exception that occurs during the upload process Log::error('File upload failed: ' . $e->getMessage()); return back()->with('error', 'Something went wrong while uploading the files.'); } } }

Step 7: Create the uploads Directory

Make sure this directory exists in your project:

mkdir public/uploads chmod -R 775 public/uploads

Step 8: Test Your Application

  1. Visit /set-upload-name to set the session upload name.

  2. Go to /upload and upload multiple files.

  3. Check the a uploads table in MySQL to confirm the records.

  4. Review storage/logs/laravel.log for success/error logs.

Conclusion

In this tutorial, you learned how to:

  • Upload multiple files in Laravel 12.

  • Store file names, upload batch name (from session), and timestamps in MySQL.

  • Use try-catch blocks for error handling.

  • Write logs using Laravel's Log facade.

Souy Soeng

Souy Soeng

Our website teaches and reads PHP, Framework Laravel, and how to download Admin template sample source code free. Thank you for being so supportive!

Github

Post a Comment

CAN FEEDBACK
close