• Fri, Mar 2026

Laravel File Uploads: Handling Images, PDFs, and More

Laravel File Uploads: Handling Images, PDFs, and More

This comprehensive tutorial will walk you through everything you need to know about handling file uploads in Laravel. From uploading images and PDFs to securing file storage and building reusable upload systems, this guide is designed to make you confident in managing files in Laravel applications.

Introduction

File uploads are one of the most common and essential features in modern web applications. Whether you’re building a blog that lets users upload profile pictures, an e-commerce system where admins upload product images, or a document management system where files like PDFs and Word docs are shared—file handling is unavoidable.

Laravel, being a modern PHP framework, provides a robust and secure way to handle file uploads. With built-in features for validation, storage abstraction, and easy retrieval, developers can implement clean and flexible file handling in their applications.

Why File Uploads Matter

Before diving into Laravel-specific details, let’s understand why file uploads matter:

  • User Experience: Profile pictures, attachments, and documents make apps more interactive and personalized.
  • Data Management: Companies rely on PDFs, CSVs, and reports for daily operations.
  • Dynamic Content: Uploaded images, videos, and files enrich blogs, forums, and e-commerce platforms.

Preparing Your Laravel Project

Step 1: Install Laravel


composer create-project laravel/laravel file-upload-demo
cd file-upload-demo
php artisan serve
    

Step 2: Create a Database

For this demo, create a database called file_uploads and update your .env file.


DB_DATABASE=file_uploads
DB_USERNAME=root
DB_PASSWORD=
    

Step 3: Configure Storage

Laravel comes with a storage folder for handling files. To make uploaded files accessible publicly, run:


php artisan storage:link
    

Building the File Upload Feature

Step 1: Create Migration

We’ll create a migration for storing uploaded files metadata.


php artisan make:migration create_files_table --create=files
    

// database/migrations/xxxx_xx_xx_create_files_table.php
public function up()
{
    Schema::create('files', function (Blueprint $table) {
        $table->id();
        $table->string('name');
        $table->string('path');
        $table->string('type')->nullable();
        $table->timestamps();
    });
}
    

Step 2: Run Migration


php artisan migrate
    

Step 3: Create Model


php artisan make:model File
    

// app/Models/File.php
namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class File extends Model
{
    protected $fillable = ['name', 'path', 'type'];
}
    

Step 4: Create Controller


php artisan make:controller FileController
    

// app/Http/Controllers/FileController.php
namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\File;

class FileController extends Controller
{
    public function index()
    {
        $files = File::all();
        return view('files.index', compact('files'));
    }

    public function store(Request $request)
    {
        $request->validate([
            'file' => 'required|mimes:jpg,jpeg,png,pdf|max:2048'
        ]);

        $uploadedFile = $request->file('file');
        $filename = time().'_'.$uploadedFile->getClientOriginalName();
        $path = $uploadedFile->storeAs('uploads', $filename, 'public');

        File::create([
            'name' => $filename,
            'path' => $path,
            'type' => $uploadedFile->getClientMimeType()
        ]);

        return back()->with('success', 'File uploaded successfully.');
    }
}
    

Step 5: Define Routes


// routes/web.php
use App\Http\Controllers\FileController;

Route::get('files', [FileController::class, 'index'])->name('files.index');
Route::post('files', [FileController::class, 'store'])->name('files.store');
    

Step 6: Create Blade View

<!-- resources/views/files/index.blade.php -->
<!DOCTYPE html>
<html>
<head>
  <title>File Upload Demo</title>
</head>
<body>
@if(session('success'))
  <p >{{ session('success') }}</p>
@endif

<form action="{{ route('files.store') }}" method="POST" enctype="multipart/form-data">
  @csrf
  <input type="file" name="file" required>
  <button type="submit">Upload</button>
</form>

<h2>Uploaded Files</h2>
<ul>
  @foreach($files as $file)
    <li>
      <a href="{{ asset('storage/'.$file->path) }}" target="_blank">
        {{ $file->name }}
      </a>
    </li>
  @endforeach
</ul>
</body>
</html>

Validating File Uploads

Laravel provides robust validation rules to ensure uploaded files meet requirements:

  • mimes:jpg,jpeg,png,pdf → restricts file type
  • max:2048 → restricts size to 2MB
  • required → ensures a file is uploaded

Example:


$request->validate([
  'file' => 'required|mimes:jpg,jpeg,png,pdf|max:2048'
]);
    

Handling Multiple File Uploads

To upload multiple files, simply add the multiple attribute to your input:

<input type="file" name="files[]" multiple>

foreach ($request->file('files') as $uploadedFile) {
    $filename = time().'_'.$uploadedFile->getClientOriginalName();
    $path = $uploadedFile->storeAs('uploads', $filename, 'public');

    File::create([
        'name' => $filename,
        'path' => $path,
        'type' => $uploadedFile->getClientMimeType()
    ]);
}
    

Storing Files in Different Disks

Laravel supports local, public, and cloud storage like Amazon S3 and Google Drive. Configure in config/filesystems.php.

DiskDescriptionUse Case
localStores files in storage/appPrivate application data
publicStores files in storage/app/publicAccessible files (images, documents)
s3Amazon S3 bucket storageCloud file hosting

Security Considerations

  • Validate file type and size to prevent malicious uploads.
  • Store files outside public if they’re not meant to be accessed directly.
  • Rename files to prevent overwriting and information leaks.

Advanced Features

Generating File Download Response


return response()->download(storage_path('app/public/'.$file->path));
    

Deleting Files


Storage::disk('public')->delete($file->path);
$file->delete();
    

Conclusion

File uploads are a powerful feature in Laravel applications. With its built-in validation, storage abstraction, and secure handling, Laravel makes it easy to implement everything from simple image uploads to advanced document management systems.

By following this tutorial, you now know how to upload, validate, store, and manage files (images, PDFs, and more) in Laravel. With practice, you can extend this knowledge to build professional file handling systems that serve real-world needs.

This website uses cookies to enhance your browsing experience. By continuing to use this site, you consent to the use of cookies. Please review our Privacy Policy for more information on how we handle your data. Cookie Policy