Hi there! I’m excited to share with you a simple guide on how to handle file uploads in Laravel 12. Whether you’re building a website that needs users to upload a single image or multiple files at once, Laravel makes it super easy.
Plus, I’ll show you how to add a cool progress bar to make the upload process more interactive. In this article, I’ll walk you through everything step-by-step, from setting up your Laravel project to adding a progress bar for a better user experience.
First, I need to create a new Laravel 12 project. If you haven’t installed Laravel yet, you can do so using Composer. Open your terminal and run:
composer create-project laravel/laravel laravel-file-upload
Once the project is set up, navigate to the project directory:
cd laravel-file-upload
Next, I’ll set up the database. Open the .env
file and configure your database connection:
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel_file_upload
DB_USERNAME=your_username
DB_PASSWORD=your_password
Run the migration to set up the default tables:
php artisan migrate
Now, I’ll create a form to allow users to upload files. I’ll use Bootstrap for styling to keep things simple. Create a new Blade file at resources/views/upload.blade.php
:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Laravel 12 File Upload</title>
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container mt-5">
<h2>Laravel 12 File Upload</h2>
@if (session('success'))
<div class="alert alert-success">{{ session('success') }}</div>
@endif
@if ($errors->any())
<div class="alert alert-danger">
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
<form action="{{ route('file.upload') }}" method="POST" enctype="multipart/form-data">
@csrf
<div class="mb-3">
<label for="file" class="form-label">Choose File (Single)</label>
<input type="file" name="file" class="form-control">
</div>
<div class="mb-3">
<label for="files" class="form-label">Choose Files (Multiple)</label>
<input type="file" name="files[]" class="form-control" multiple>
</div>
<button type="submit" class="btn btn-primary">Upload</button>
</form>
</div>
</body>
</html>
This form allows users to upload a single file or multiple files at once.
I’ll define routes to display the form and handle the file upload. Open routes/web.php
and add:
use App\Http\Controllers\FileUploadController;
Route::get('/upload', [FileUploadController::class, 'showForm'])->name('upload.form');
Route::post('/upload', [FileUploadController::class, 'upload'])->name('file.upload');
Next, I’ll create a controller to handle the form submission and file storage. Run this Artisan command to generate a controller:
php artisan make:controller FileUploadController
Open app/Http/Controllers/FileUploadController.php
and add the following code:
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
class FileUploadController extends Controller
{
public function showForm()
{
return view('upload');
}
public function upload(Request $request)
{
// Validate single file
$request->validate([
'file' => 'nullable|file|max:2048', // Max 2MB
'files.*' => 'nullable|file|max:2048', // Max 2MB per file
]);
// Handle single file upload
if ($request->hasFile('file')) {
$file = $request->file('file');
$fileName = time() . '_' . $file->getClientOriginalName();
$file->storeAs('uploads', $fileName, 'public');
}
// Handle multiple file uploads
if ($request->hasFiles('files')) {
foreach ($request->file('files') as $file) {
$fileName = time() . '_' . $file->getClientOriginalName();
$file->storeAs('uploads', $fileName, 'public');
}
}
return back()->with('success', 'Files uploaded successfully!');
}
}
This controller validates and stores both single and multiple files in the public/storage/uploads
directory.
To make uploaded files accessible, I’ll link the storage directory. Run:
php artisan storage:link
This creates a symbolic link from public/storage
to storage/app/public
. Files will be stored in storage/app/public/uploads
.
To enhance the user experience, I’ll add a progress bar using JavaScript and Axios. First, include Axios and add a progress bar to the form. Update resources/views/upload.blade.php
:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Laravel 12 File Upload</title>
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container mt-5">
<h2>Laravel 12 File Upload</h2>
@if (session('success'))
<div class="alert alert-success">{{ session('success') }}</div>
@endif
@if ($errors->any())
<div class="alert alert-danger">
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
<form id="uploadForm" action="{{ route('file.upload') }}" method="POST" enctype="multipart/form-data">
@csrf
<div class="mb-3">
<label for="file" class="form-label">Choose File (Single)</label>
<input type="file" name="file" class="form-control">
</div>
<div class="mb-3">
<label for="files" class="form-label">Choose Files (Multiple)</label>
<input type="file" name="files[]" class="form-control" multiple>
</div>
<div class="progress mb-3" style="display: none;">
<div class="progress-bar" role="progressbar" style="width: 0%;" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100">0%</div>
</div>
<button type="submit" class="btn btn-primary">Upload</button>
</form>
</div>
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
<script>
document.getElementById('uploadForm').addEventListener('submit', function(e) {
e.preventDefault();
const form = this;
const progressBar = document.querySelector('.progress');
const progressBarInner = document.querySelector('.progress-bar');
progressBar.style.display = 'block';
progressBarInner.style.width = '0%';
progressBarInner.textContent = '0%';
const formData = new FormData(form);
axios.post(form.action, formData, {
onUploadProgress: function(progressEvent) {
const percentCompleted = Math.round((progressEvent.loaded * 100) / progressEvent.total);
progressBarInner.style.width = percentCompleted + '%';
progressBarInner.textContent = percentCompleted + '%';
}
})
.then(response => {
progressBar.style.display = 'none';
window.location.reload(); // Refresh to show success message
})
.catch(error => {
progressBar.style.display = 'none';
alert('Error uploading files!');
});
});
</script>
</body>
</html>
This code uses Axios to handle the form submission asynchronously and updates the progress bar as the upload progresses.
Start the Laravel development server:
php artisan serve
Visit http://localhost:8000/upload
in your browser. Try uploading a single file and multiple files. The progress bar will show the upload progress, and a success message will appear once the upload is complete.
In this guide, I’ve shown you how to implement single and multiple file uploads in Laravel 12 and add a progress bar to improve the user experience. Laravel’s built-in features, like the Storage facade and validation, make file handling a breeze. Adding a progress bar with Axios is a simple way to make your application more interactive. I hope this tutorial helps you add file upload functionality to your Laravel projects with ease!
Q1: What file types can I upload with Laravel?
You can upload any file type, but you should validate the file types in the controller. For example, use mimes:jpg,png,pdf
in the validation rules to allow only specific formats.
Q2: How do I increase the file size limit in Laravel?
To increase the file size limit, update upload_max_filesize
and post_max_size
in your php.ini
file. For example, set upload_max_filesize=10M
and post_max_size=10M
. Then, restart your server.
Q3: Can I store files in cloud storage like Amazon S3?
Yes! Laravel supports cloud storage like Amazon S3. Configure the filesystems.php
config file to use the s3
disk and set up your S3 credentials in the .env
file.
Q4: Why is my progress bar not showing?
Ensure Axios is loaded correctly and your form has the enctype="multipart/form-data"
attribute. Also, check the browser’s console for any JavaScript errors.
Q5: How can I secure file uploads in Laravel?
Always validate file types and sizes in your controller. Use Laravel’s built-in validation rules and consider adding antivirus scanning for uploaded files to enhance security.
You might also like :