Laravel 12 Upload Multiple Files : A Step-by-Step Guide

Author

Kritim Yantra

Mar 26, 2025

Laravel 12 Upload Multiple Files : A Step-by-Step Guide

Uploading multiple files in Laravel is a common requirement for applications that handle images, documents, or media. Laravel makes it easy to process multiple file uploads with built-in validation and storage features.

In this guide, we’ll cover how to upload multiple files in Laravel 12 with detailed steps, including form setup, validation, and storage.


Prerequisites

Before starting, ensure you have:

  • Laravel 12 installed
  • Basic knowledge of Laravel MVC structure
  • A configured storage system (local or cloud)

Step 1: Set Up a Form for Multiple File Uploads

First, create a Blade view (resources/views/upload.blade.php) with a form that supports multiple file uploads:

<!DOCTYPE html>
<html>
<head>
    <title>Upload Multiple Files</title>
</head>
<body>
    <h1>Upload Multiple Files</h1>
    
    <form action="{{ route('upload.files') }}" method="POST" enctype="multipart/form-data">
        @csrf
        <input type="file" name="files[]" multiple>
        <button type="submit">Upload</button>
    </form>

    @if(session('success'))
        <div style="color: green;">
            {{ session('success') }}
        </div>
    @endif

    @if($errors->any())
        <div style="color: red;">
            <ul>
                @foreach($errors->all() as $error)
                    <li>{{ $error }}</li>
                @endforeach
            </ul>
        </div>
    @endif
</body>
</html>

Key Notes:

  • enctype="multipart/form-data" is required for file uploads.
  • name="files[]" allows multiple file selection.
  • multiple enables multi-select in the file input.

Step 2: Create a Route for File Upload

Define a route in routes/web.php:

use Illuminate\Support\Facades\Route;
use App\Http\Controllers\FileUploadController;

Route::get('/upload', function () {
    return view('upload');
});

Route::post('/upload', [FileUploadController::class, 'upload'])->name('upload.files');

Step 3: Create a Controller to Handle Uploads

Generate a controller:

php artisan make:controller FileUploadController

Then, update app/Http/Controllers/FileUploadController.php:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;

class FileUploadController extends Controller
{
    public function upload(Request $request)
    {
        // Validate files
        $request->validate([
            'files.*' => 'required|file|mimes:jpg,png,pdf|max:2048', // 2MB max per file
        ]);

        // Check if files were uploaded
        if ($request->hasFile('files')) {
            foreach ($request->file('files') as $file) {
                // Store each file in the 'public/uploads' directory
                $path = $file->store('uploads', 'public');
                
                // Optional: Save file info to the database
                // File::create(['filename' => $path]);
            }

            return back()->with('success', 'Files uploaded successfully!');
        }

        return back()->with('error', 'No files selected.');
    }
}

Explanation:

  • files.* validates each file in the array.
  • mimes:jpg,png,pdf restricts file types.
  • max:2048 sets a 2MB limit per file.
  • store('uploads', 'public') saves files in storage/app/public/uploads.

Step 4: Configure Storage (Laravel's Public Disk)

By default, Laravel stores files in storage/app. To make them publicly accessible:

  1. Create a symbolic link (to link storage/app/public to public/storage):

    php artisan storage:link
    
  2. Configure config/filesystems.php (optional):

    'disks' => [
        'public' => [
            'driver' => 'local',
            'root' => storage_path('app/public'),
            'url' => env('APP_URL').'/storage',
            'visibility' => 'public',
        ],
    ],
    

Step 5: Display Uploaded Files

To display uploaded files, modify the Blade view (upload.blade.php):

@if(Storage::disk('public')->exists('uploads'))
    <h2>Uploaded Files:</h2>
    <ul>
        @foreach(Storage::disk('public')->files('uploads') as $file)
            <li>
                <a href="{{ Storage::url($file) }}" target="_blank">
                    {{ basename($file) }}
                </a>
            </li>
        @endforeach
    </ul>
@endif

Notes:

  • Storage::url() generates a public URL (e.g., http://your-app/storage/uploads/file.jpg).
  • basename() extracts the filename from the path.

Step 6: Store File Info in Database (Optional)

To track uploaded files, create a files table:

  1. Generate a migration & model:

    php artisan make:model File -m
    
  2. Update the migration (database/migrations/..._create_files_table.php):

    public function up()
    {
        Schema::create('files', function (Blueprint $table) {
            $table->id();
            $table->string('filename');
            $table->timestamps();
        });
    }
    
  3. Run the migration:

    php artisan migrate
    
  4. Update the FileUploadController to save records:

    use App\Models\File;
    
    foreach ($request->file('files') as $file) {
        $path = $file->store('uploads', 'public');
        File::create(['filename' => $path]);
    }
    

Step 7: Handle Errors & Edge Cases

  • Large File Uploads: Increase upload_max_filesize and post_max_size in php.ini.
  • File Type Restrictions: Modify mimes: in validation.
  • Duplicate Filenames: Use $file->hashName() instead of original names:
    $path = $file->storeAs('uploads', $file->hashName(), 'public');
    

Conclusion

You’ve now learned how to:
✅ Upload multiple files in Laravel 12
✅ Validate file types and sizes
✅ Store files securely
✅ Display uploaded files
✅ Save file data in the database

This approach works for images, PDFs, and other file types, making it versatile for various applications.

Now you can implement multiple file uploads in your Laravel app with confidence! 🚀

Tags

Laravel Php

Comments

No comments yet. Be the first to comment!

Please log in to post a comment:

Continue with Google

Related Posts

Laravel 12 CRUD Application with React, InertiaJS & Tailwind CSS
Kritim Yantra Kritim Yantra
Feb 27, 2025
Laravel 12 Roles and Permissions Setup: Complete Guide
Kritim Yantra Kritim Yantra
Feb 28, 2025
Laravel 12 & AdminLTE Integration: Setup Your Stunning Admin Dashboard
Kritim Yantra Kritim Yantra
Feb 28, 2025