Laravel 12 File Upload with Validation Example

Laravel 12 File Upload with Validation Example

Laravel 12 File Upload with Validation Example

File uploading is one of the most common features in web applications. In this tutorial, you will learn how to implement file upload with validation in a Laravel 12 application using the Storage facade.

Step 1: Install Laravel 12

Create a fresh Laravel application if you don't already have one:

composer create-project laravel/laravel file-upload-app

Step 2: Create the Upload Form

Create a Blade view at resources/views/upload.blade.php with a file input and CSRF token:

<!DOCTYPE html>
<html>
<head><title>File Upload</title></head>
<body>
    @if (session('success'))
        <p style="color:green">{{ session('success') }}</p>
    @endif

    @if ($errors->any())
        <ul>@foreach ($errors->all() as $e) <li>{{ $e }}</li> @endforeach</ul>
    @endif

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

Step 3: Create a Form Request for Validation

Generate a Form Request to keep validation logic out of your controller:

php artisan make:request UploadFileRequest

Open app/Http/Requests/UploadFileRequest.php and define the rules:

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class UploadFileRequest extends FormRequest
{
    public function authorize(): bool
    {
        return true;
    }

    public function rules(): array
    {
        return [
            'document' => [
                'required',
                'file',
                'mimes:pdf,doc,docx,jpg,jpeg,png',
                'max:5120', // 5 MB
            ],
        ];
    }

    public function messages(): array
    {
        return [
            'document.required' => 'Please select a file to upload.',
            'document.mimes'    => 'Only PDF, Word, and image files are allowed.',
            'document.max'      => 'The file must not exceed 5 MB.',
        ];
    }
}

Step 4: Create the Controller

php artisan make:controller UploadController

Open app/Http/Controllers/UploadController.php and add the upload logic:

namespace App\Http\Controllers;

use App\Http\Requests\UploadFileRequest;
use Illuminate\Http\RedirectResponse;
use Illuminate\View\View;

class UploadController extends Controller
{
    public function create(): View
    {
        return view('upload');
    }

    public function store(UploadFileRequest $request): RedirectResponse
    {
        // Store in storage/app/public/uploads — publicly accessible
        $path = $request->file('document')->store('uploads', 'public');

        return redirect()->route('upload.create')
            ->with('success', "File uploaded successfully: $path");
    }
}

Step 5: Define Routes

use App\Http\Controllers\UploadController;

Route::get('/upload', [UploadController::class, 'create'])->name('upload.create');
Route::post('/upload', [UploadController::class, 'store'])->name('upload.store');

Step 6: Create the Storage Symlink

Run the following command to make uploaded files publicly accessible via the browser:

php artisan storage:link

Files stored in storage/app/public/uploads will be accessible at /storage/uploads/filename.

Step 7: Retrieve Uploaded Files

To display or link to an uploaded file, use the Storage facade:

use Illuminate\Support\Facades\Storage;

// Get the public URL
$url = Storage::url($path); // e.g. /storage/uploads/abc123.pdf

// Check if file exists
Storage::disk('public')->exists('uploads/abc123.pdf');

// Delete a file
Storage::disk('public')->delete('uploads/abc123.pdf');

Step 8: Test the Application

php artisan serve

Open http://127.0.0.1:8000/upload in your browser and try uploading different file types to test the validation rules.

All Comments