Uploading images is one of the most common tasks in web development. But if done naively, your controllers get cluttered with repetitive code for uploading, deleting, and managing files.
In this article, we'll create a **reusable Image Helper** in Laravel that you can use across your entire project — keeping your code **clean**, **DRY**, and **easy to maintain**.
## Problem
Most beginner Laravel developers end up writing repetitive code like this:
if ($request->hasFile('logo')) {
$file = $request->file('logo');
$filename = time().'_'.$file->getClientOriginalName();
$file->move(public_path('storage/company'), $filename);
$company->logo = 'company/' . $filename;
}
And for deleting images:
if ($company->logo) {
$imagePath = public_path('storage/' . $company->logo);
if (file_exists($imagePath)) {
unlink($imagePath);
}
}
The more image fields you have, the messier your controller becomes.
Solution: Reusable Image Helper
Instead of repeating the same code everywhere, we create a single helper that handles both uploading and deleting images. This helper can be used anywhere in your project, for logos, avatars, PDFs, or any file.
Step 1: Create the Helper
Create a file:
app/Helpers/ImageHelper.php
<?php
namespace App\Helpers;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Str;
class ImageHelper
{
// Upload image
public static function uploadImage($file, $folder, $oldFilePath = null)
{
// Delete old file if exists
if ($oldFilePath) {
self::deleteImage($oldFilePath);
}
// Generate a unique filename
$filename = Str::uuid() . '_' . $file->getClientOriginalName();
// Create folder if not exists
$destination = public_path('storage/' . $folder);
if (!File::exists($destination)) {
File::makeDirectory($destination, 0755, true);
}
// Move file
$file->move($destination, $filename);
return $folder . '/' . $filename;
}
// Delete image
public static function deleteImage($path)
{
$fullPath = public_path('storage/' . $path);
if (File::exists($fullPath)) {
File::delete($fullPath);
return true;
}
return false;
}
}
💡 Tip: Using Str::uuid()
ensures your filenames are globally unique, avoiding conflicts if multiple users upload files simultaneously.
Step 2: Autoload the Helper
In composer.json
:
"autoload": {
"files": [
"app/Helpers/ImageHelper.php"
]
}
Then run:
composer dump-autoload
Step 3: Use in Controller
Now your controller becomes super clean:
use App\Helpers\ImageHelper;
if ($request->hasFile('logo')) {
$companyData['logo'] = ImageHelper::uploadImage(
$request->file('logo'),
'company',
$company->logo // old file path to delete
);
}
if ($request->hasFile('favicon')) {
$companyData['favicon'] = ImageHelper::uploadImage(
$request->file('favicon'),
'company',
$company->favicon
);
}
$company->update($companyData);
Step 4: Delete Old Images (Optional)
ImageHelper::deleteImage($client->img);
This ensures no orphan files remain in your public/storage
folder.
Benefits
- Cleaner controllers
- Reusable across multiple projects
- Handles both upload and delete
- Auto-creates folders
- Filename conflicts minimized with
Str::uuid()
- Works perfectly with cPanel hosting
Conclusion
With this helper, you never have to repeat your file upload or delete logic. It's plug-and-play, Laravel-friendly, and fully compatible with shared hosting environments.
Whether you're building a CMS, e-commerce site, or any Laravel project, this helper saves time, keeps your code DRY, and standardizes image handling.
Next Steps / Ideas:
- Extend the helper to handle other file types like PDFs, videos, or docs.
- Add image resizing or thumbnails using
Intervention/Image
. - Combine with user avatars or multi-image uploads for galleries.