Skip to main content
Laravel 9 File Upload Tutorial Step by Step

Laravel 9 File Upload Tutorial Step by Step

On a website, the file upload function is frequently used. For example, if we want to change our profile photo, we must first upload the photo file. Laravel 9 includes a magical feature that simplifies and secures the process of creating a file upload function.

For this reason, in this tutorial, we will create a file upload function using the Laravel 9 framework step by step.

Let’s get right to the tutorial for creating the file upload function.

Tutorial for Uploading File With Laravel 9

There are a few things that must be done before creating a file upload function in Laravel:

  • Laravel 9 Framework. One of the most popular PHP frameworks is Laravel. Make sure we have Laravel installed on our computer before proceeding with the tutorial. Read more: Install Laravel on Windows Step by Step
  • Text Editor. Used to write program code. Visual Studio Code will be our text editor of choice. Visual Studio Code has many features that will come in handy later.
  • Web Browser. We used it to run the Laravel 9 website we built. As a web browser, we will be using Google Chrome in this tutorial.

If the tools listed above are ready, we can move on to the stages of creating a file upload with the five simple steps listed below:

1. Add File Upload Route (web.php)

We can add routes to Laravel by opening the routes/web.php file. Here we will add several file uploading routes, namely:

  • Get Route. The controller in charge of displaying the page will handle this route.
  • Post Route. Used to save uploaded file.
  • Delete Route. Used to delete uploaded file.

To add the above route, add the following code to the web.php file:

<?php

use App\Http\Controllers\FileUploadController;
use Illuminate\Support\Facades\Route;

/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/

Route::controller(FileUploadController::class)->group(function () {
    Route::get('/', 'index')->name('index');
    Route::post('/', 'store')->name('store');
    Route::delete('/', 'destroy')->name('destroy');
});

2. Create Controller File (FileUploadController.php)

Following that, we must create a controller that contains the logic for uploading file. We can create a controller in Laravel by using the following command:

php artisan make:controller FileUploadController

We can execute the command using the terminal provided by Visual Studio Code. When the command is successfully executed, a FileUploadController.php file is created in the app/Http/Controllers folder.

FileUploadController.php in Visual Studio Code
FileUploadController.php in Visual Studio Code

In this controller file, we will write three methods:

  • index Method. Used to handle the get route that displays the file upload page.
  • store Method. Used to handle the post route that saves the uploaded file. Uploaded files will be saved in the storage/app/public/images folder.
  • destroy Method. Used to handle the destroy route, which deletes uploaded file.

These methods can be written in FileUploadController.php as follows:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;

class FileUploadController extends Controller
{
    public function index()
    {
        $images = Storage::disk('public')->files('images');
        return view('file_upload', ['images' => $images]);
    }

    public function store(Request $request)
    {
        $request->validate([
            'image' => ['required', 'image', 'file'],
        ]);

        $request->file('image')->store('images', 'public');

        return redirect()->route('index');
    }

    public function destroy(Request $request)
    {
        $validated = $request->validate([
            'path' => ['required'],
        ]);

        Storage::disk('public')->delete($validated['path']);

        return redirect()->route('index');
    }
}

3. Create a File Upload View (file_upload.blade.php)

The view file is a display file that the user will see. In the resources/views folder, we will create an view file called file_upload.blade.php. After we’ve created the file, we can add the following code to it:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Laravel 9 File Upload - Sribuhost</title>

    <link rel="stylesheet" href="{{ asset('style.css') }}" />
</head>

<body>
    <div class="container">
        <h1 class="title">Laravel 9 File Upload - <a href="https://sribuhost.com" target="_blank">Sribuhost</a></h1>
        <p class="subtitle">
            Upload and delete file using Laravel 9 framework.
        </p>
        <hr />
        <form action="{{ route('store') }}" method="POST" enctype="multipart/form-data" class="form">
            @csrf
            <div class="form__group">
                <label for="image" class="form__label">Select an image</label>
                <input type="file" name="image" id="image" class="form__file" accept="image/*" required />
            </div>
            <button type="submit" class="button button_primary">Upload</button>
        </form>
        <table class="table">
            <tr>
                <th>Preview</th>
                <th>Size</th>
                <th>Last Modified</th>
                <th>Action</th>
            </tr>
            @foreach ($images as $image)
                <tr>
                    <td><img src="{{ asset('storage/' . $image) }}" alt="" class="img-thumbnail" /></td>
                    <td>{{ Storage::disk('public')->size($image) / 1000 }} KB</td>
                    <td>{{ date('d M Y', Storage::disk('public')->lastModified($image)) }}</td>
                    <td>
                        <form action="{{ route('destroy') }}" method="POST">
                            @method('DELETE')
                            @csrf
                            <input type="hidden" name="path" value="{{ $image }}">
                            <button type="submit" class="button button_danger button_sm">Delete</button>
                        </form>
                    </td>
                </tr>
            @endforeach
        </table>
    </div>
</body>

</html>

4. Add Style to View (style.css)

To improve the appearance of the displayed view file, we will include style code in public/style.css. Here is the style code that was created:

@import url("https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&display=swap");

* {
    box-sizing: border-box;
}

html {
    font-family: "Roboto", sans-serif;
    font-size: 16px;
}

body {
    background-color: #fff;
    color: #666;
    margin: 0;
    padding: 4rem 0;
}

a {
    text-decoration: none;
}

a:hover {
    text-decoration: underline;
}

.container {
    margin-inline: auto;
    max-width: 1024px;
}

.title {
    color: #444;
    margin: 0;
    margin-bottom: 0.5rem;
}

.subtitle {
    margin-block: 0.5rem;
}

hr {
    border: none;
    border-bottom: 1px solid #ddd;
    margin-block: 1.5rem;
}

.form {
    margin-bottom: 3rem;
}

.form__group {
    align-items: flex-start;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    margin-bottom: 1rem;
}

.form__file {
    font-family: inherit;
    font-size: 0.875rem;
}

.button {
    background-color: transparent;
    border: none;
    border-radius: 0.25rem;
    color: inherit;
    cursor: pointer;
    font-family: inherit;
    font-size: 0.875rem;
    padding: 0.5rem 1rem;
    transition: all 0.15s;
}

.button_primary {
    background-color: #265973;
    color: #fff;
}

.button_primary:hover {
    background-color: #23495c;
}

.button_danger {
    background-color: #a32929;
    color: #fff;
}

.button_danger:hover {
    background-color: #8a2828;
}

.button_sm {
    font-size: 0.75rem;
    padding: 0.375rem 0.75rem;
}

.table {
    border: 1px solid #ccc;
    border-collapse: collapse;
    font-size: 0.875rem;
    text-align: center;
    width: 100%;
}

.table th {
    background-color: #f2f2f2;
    color: #444;
}

.table th,
.table td {
    border: 1px solid #ccc;
    padding: 0.75rem 1rem;
    vertical-align: top;
}

.img-thumbnail {
    border: 1px solid #ccc;
    border-radius: 0.25rem;
    height: 100vh;
    max-height: 4rem;
    max-width: 8rem;
    object-fit: cover;
    width: 100vw;
}

5. Try Uploading File

After all of the files have been created, we can run it in a web browser. Because we will be displaying uploaded files, we must create a symbolic link from public/storage to storage/app/public so that uploaded files can be accessed via a browser. The following command can be used:

php artisan storage:link

We must also start the local server with the following command:

php artisan serve

In a web browser, enter the url displayed by the terminal.

Terminal in Visual Studio Code
Terminal in Visual Studio Code
Laravel File Upload in Web Browser
Laravel File Upload in Web Browser

We can upload file here by first selecting the file to be uploaded and then clicking Upload button. The uploaded file will be displayed in the table later.

Uploaded File in Web Browser
Uploaded File in Web Browser

By clicking the Delete button, we can also remove uploaded files.

Makes the File Upload Function Very Easy Right?

That’s how to upload a file in Laravel 9. We can upload files in just 5 simple steps. This tutorial’s source code can be found on Sribuhost github repository here. If you have any questions, please leave them in the comments section.

If you find it useful, please share it. Thank you very much.

Share this

Shafy Gunawan

I’m a web developer. I spend my whole day, practically every day, experimenting with HTML, CSS, JavaScript, and PHP; dabbling with Python programming language; and share the knowledge that I learned.

One thought to “Laravel 9 File Upload Tutorial Step by Step”

  1. Hi! Someone in my Myspace group shared this site with us so I came to look it over. I’m definitely enjoying the information. I’m book-marking and will be tweeting this to my followers! Superb blog and terrific style and design.

Leave a Reply

Your email address will not be published. Required fields are marked *