Mahamudul Hasan Rubel
HomeAboutProjectsSkillsExperienceBlogPhotosContact
Mahamudul Hasan Rubel

Senior Software Engineer crafting high-performance web applications and SaaS platforms.

Navigation

  • Home
  • About
  • Projects
  • Skills
  • Experience
  • Blog
  • Photos
  • Contact

Get in Touch

Available for senior/lead roles and consulting.

bd.mhrubel@gmail.comHire Me

© 2026 Mahamudul Hasan Rubel. All rights reserved.

Built with using Next.js 16 & Tailwind v4

Back to Blog
LaravelPHPJune 21, 20264 min read

Mastering Laravel Storage: A Beginner’s Guide to File Uploads

Master Laravel storage for file uploads with this practical guide. Learn how to handle local and cloud files using the filesystem facade efficiently.

LaravelPHPWeb DevelopmentFile UploadsStorageTutorial

Dealing with user-uploaded files used to be a nightmare in PHP. You’d have to worry about move_uploaded_file, checking permissions, and writing custom logic just to swap from a local folder to an S3 bucket. When I first started with Laravel, I realized the Storage facade abstracts all that away, letting me focus on the actual business logic rather than filesystem quirks.

Understanding Laravel storage and the Filesystem

Laravel’s filesystem abstraction is built on top of the Flysystem library. This is why you can write code that works on your local machine during development and on AWS S3 in production without changing a single line of your core logic.

When you start a new project, everything lives in the local disk defined in your config/filesystems.php file. By default, this points to storage/app.

I remember early in my career, I tried writing files directly to the public/ directory using standard PHP functions. It worked until we deployed to a load-balanced environment, and the files were stuck on one server. That’s when I learned that using Laravel storage is a non-negotiable best practice for any application that needs to scale.

Handling basic file uploads

To get started, you need a form with enctype="multipart/form-data". In your controller, handling the upload is incredibly straightforward.

PHP
public function store(Request $request)
{
    $request->validate([
        'avatar' => 'required|image|max:2048',
    ]);

    $path = $request->file('avatar')->store('avatars', 'public');

    return response()->json(['path' => $path]);
}

Here, the store method takes two arguments: the folder path and the disk name. By using the public disk, Laravel creates a symbolic link from public/storage to storage/app/public. This allows your users to access the file via a URL. If you forget to run php artisan storage:link, you'll spend about 20 minutes wondering why your images are returning a 404. I’ve been there—don't be like me.

Why you need a driver-based approach

Using the Storage facade is about more than just convenience; it’s about decoupling. If you ever need to move from local storage to S3, you just update your .env file:

TEXT
FILESYSTEM_DISK=s3
AWS_ACCESS_KEY_ID=your-key
AWS_SECRET_ACCESS_KEY=your-secret
...

Once you install the necessary S3 adapter via Composer (composer require league/flysystem-aws-s3-v3), your existing code remains untouched. This is the beauty of a proper service-oriented architecture. If you’re interested in how this fits into the broader ecosystem, you might want to look into how Mastering Laravel Facades for Cleaner, Expressive Service Interfaces works under the hood to make this possible.

Common pitfalls with file uploads

I’ve seen junior developers run into the same three issues repeatedly:

  1. Massive file sizes: Always validate the file size in your request validation. Don't rely on the server's upload_max_filesize alone, as that returns a cryptic error.
  2. Naming collisions: If two users upload profile.jpg, the second one will overwrite the first. Use storeAs() or store() to generate unique filenames.
  3. Queueing heavy processing: If you’re resizing images, don't do it in the request cycle. Use Mastering Laravel Queues: A Beginner’s Guide to Background Processing to handle the heavy lifting after the file is saved.

FAQ: Frequently asked questions

Q: Should I store files in the database? A: Generally, no. Store the file path in the database and the actual file on the disk (local or cloud). Storing blobs in a database makes backups massive and slows down your queries significantly.

Q: How do I delete a file? A: It’s as simple as Storage::disk('public')->delete($path);. Just ensure you have the correct path stored in your database record.

Q: Is local storage safe for production? A: It's fine for small, single-server apps. However, once you scale to multiple servers, you must move to a shared driver like S3 or a dedicated file server to keep your application state consistent.

Final thoughts

Mastering Laravel file storage is one of those skills that makes you feel like you've finally stopped fighting the framework and started working with it. Start by keeping it simple: use the local disk, get your symlinks set up, and make sure your validation is tight.

I’m still occasionally surprised by the edge cases—like weird file encoding or permissions issues on Linux servers—but that’s part of the job. Next time you're setting up a file upload, try to think about how you'd handle the storage if you had to switch providers tomorrow. If your code is already using the Storage facade, you’re already halfway there.

Back to Blog

Similar Posts

LaravelPHPJune 21, 20264 min read

Laravel Mail: A Beginner's Guide to Sending Transactional Emails

Master Laravel Mail to send transactional emails and notifications with ease. Learn how to configure drivers, build Mailables, and handle queues properly.

Read more
LaravelPHP
June 21, 2026
4 min read

Laravel Eloquent Relationships: A Guide to Linking Data Models

Master Laravel Eloquent database relationships like hasMany and belongsTo. Learn to link your models efficiently with this practical guide for PHP developers.

Read more
Close-up of three wooden arrows pointing in opposite directions on a beige surface.
LaravelPHPJune 21, 20264 min read

Laravel Blade custom directives: A guide to cleaner templates

Laravel Blade custom directives help you remove repetitive logic from your views. Learn how to build and register them to keep your code DRY and readable.

Read more