CHAPTER 14
Beginner
File Uploads and Storage in Laravel
Updated: May 14, 2026
25 min read
# CHAPTER 14
File Uploads and Storage in Laravel
1. Introduction
Handling file uploads in core PHP is notoriously painful. You have to deal with the messy$_FILES superglobal, manually check MIME types, and write clunky move_uploaded_file() functions. Laravel provides a powerful, elegant abstraction over file storage called the Filesystem. Whether you are storing a profile picture on your local server or uploading a massive video directly to Amazon S3 cloud storage, Laravel's API remains exactly the same.
2. Learning Objectives
By the end of this chapter, you will be able to:- Configure a Blade form for multipart file uploads.
- Capture and validate file uploads in a Controller.
- Store files securely on the local server.
- Create a symbolic link to make uploaded files publicly accessible.
3. Beginner-Friendly Explanation
Imagine a post office. In old PHP, you had to personally grab the package from the customer, weigh it, inspect the contents, drive it to the warehouse, and put it on a specific shelf. In Laravel, you just tell the Storage Assistant: *"Take this package, check if it's an image under 2MB, and put it in the 'avatars' aisle."* Laravel instantly hashes a unique, random filename for security, saves the file to the hard drive, and hands you a piece of paper (a text string) with the exact location. You take that piece of paper and save it in your MySQL database.4. Step 1: The Blade Form
To upload files, the HTML<form> MUST have the enctype="multipart/form-data" attribute. Without it, the browser strips the file away and only sends text.
resources/views/upload.blade.php
html
5. Step 2: Validating and Storing in the Controller
When the form is submitted, the file arrives via the Request object. We validate it, and then use thestore() method.
app/Http/Controllers/UserController.php
php
6. The Public Storage Enigma (Symlinks)
Where did Laravel physically put the file? By default, Laravel stores it deep insidestorage/app/public/avatars/.
However, the internet is only allowed to see files inside your public/ directory! If you try to put an image tag like <img src="/storage/avatars/image.jpg">, the browser will show a broken image.
We must create a shortcut (Symbolic Link) that connects the hidden storage folder to the public internet folder.
Run this Artisan command ONE TIME in your terminal:
bash
This creates a magic tunnel. Now, files saved in storage/app/public are instantly accessible via the public/storage URL.
7. Displaying the Uploaded File in Blade
Now that the database holds the path (e.g.,avatars/xyz.jpg), and the symlink is created, we use the asset() helper function to generate the correct URL.
html
8. Cloud Storage (Amazon S3)
The magic of Laravel's Filesystem is that you can switch to Cloud Storage without changing your Controller code. If your website grows and you want to store images on Amazon S3 instead of your local server, you just change one line in your.env file (FILESYSTEM_DISK=s3). The $request->file('avatar')->store() command will automatically upload the file to Amazon servers!
9. Best Practices
-
Never Store Original Filenames: Laravel's
store()method automatically generates a unique 40-character hashed filename (e.g.,a7b9c...jpg). Always use this. If you let users keep their original filename, a user could upload a file namedindex.phpand trick your server into executing malicious code.
10. Common Mistakes
-
Forgetting
enctype: If your Controller says$request->hasFile('avatar')is always returningfalse, go check your HTML. You forgotenctype="multipart/form-data"in the<form>tag.
11. Exercises
-
1.
Explain the purpose of the
php artisan storage:linkcommand. Why can't the internet see files directly in thestorage/directory?
12. Coding Challenges
-
Challenge: Write the Controller validation rules for a PDF document upload. The file must be required, it must be exactly a PDF (
mimes:pdf), and it must not exceed 5 Megabytes in size.
13. MCQs with Answers
Question 1
Which HTML attribute is absolutely required on a <form> tag to allow file uploads to a Laravel backend?
Question 2
When Laravel's store('avatars', 'public') method successfully saves a file to the hard drive, what does the method return to the developer to be saved in the MySQL database?
14. Interview Questions
- Q: Describe the complete workflow of handling an image upload in Laravel, from the Blade form attributes, to Controller validation, to database storage, and finally displaying it via a symbolic link.
- Q: Why is it recommended to store file paths in a database rather than storing the binary file payload directly in a database blob column?
15. FAQs
Q: Can I delete a file from the server when a user deletes their account? A: Yes! You use the Storage facade:Storage::disk('public')->delete($user->profile_image);. This erases the physical file from the hard drive to save space.
16. Summary
In Chapter 14, we handled physical assets. By modifying our forms to accept multipart data, validating the file streams via the Request object, and utilizing Laravel'sstore() method, we securely handled user uploads. We learned the critical importance of the storage:link command to bridge our secure internal storage with the public-facing internet, allowing us to serve dynamic, user-uploaded content effortlessly.