Upload files on Laravel 10
Tags: laravel, php, fileupload, package
Published: 2023-03-07 17:20:00

Uploading files is one common feature that most of the applications use, and yet is one of the things that I see many people struggling with.

Laravel offers a simple API to work with local filesystem as simple as:

```
Storage::putFileAs('images', $request->file('file'));
```

Often user needs to handle file validation, _file size_, _dimensions_, _name_, _visibility_, _path_, _disk_ etc.

We will want to create a form that allows us to upload a file and submit it - and a route will accept this form, validate the input and handle the upload.

With this article, I will do a step-by-step file upload tutorial on Laravel 10 using [erlandmuchasaj/laravel-file-uploader](https://github.com/erlandmuchasaj/laravel-file-uploader) package. 
In this Tutorial we will generate 2 routes.
One for creating a form where user will upload the file and another route for the file to be uploaded using the package.
We will create a simple form using [Bootstrap Form UI components](https://getbootstrap.com/docs/5.2/forms/overview/).

First things first, lets setup a brand new Laravel project.
Open the command-line tool and execute the following command to create a Laravel project from scratch.

```
composer create-project laravel/laravel --prefer-dist laravel-file-uploader
```

Then we go into the freshly created project directory:

```
cd laravel-file-uploader
```

Then we install the [laravel-file-uploader](https://github.com/erlandmuchasaj/laravel-file-uploader) package.

```
composer require erlandmuchasaj/laravel-file-uploader
```

After that we create a symbolic link to access the files that are going to be publicly accessible.
By default, the `public` disk uses the `local` driver and stores its files in `storage/app/public`.

To make these files accessible from the web, you should create a symbolic link from `public/storage` to `storage/app/public`.

To create the symbolic link, you may use the storage:link Artisan command:

```
php artisan storage:link
```
## Create routes.
Go to `route/web.php` and create 2 additional routes. The first handles the form visualization and the other handles the form POST request.

```
use ErlandMuchasaj\LaravelFileUploader\FileUploader; // <= import the package
use Illuminate\Support\Facades\Route;
use Illuminate\Http\Request;


// visualize the form
Route::get('/files', function (Request $request) {
    return view('files');
})->name('files');

// handle the post request
Route::post('/files', function (Request $request) {

    $max_size = (int) ini_get('upload_max_filesize') * 1000;

    $extensions = implode(',', FileUploader::images());

    $request->validate([
        'file' => [
            'required',
            'file',
            'image',
            'mimes:' . $extensions,
            'max:'.$max_size,
        ]
    ]);

    $file = $request->file('file');

    $response = FileUploader::store($file);

    return redirect()
            ->back()
            ->with('success','File has been uploaded.')
            ->with('file', $response);
})->name('files.store');
```
## Creating the blade files in Laravel.
In this step we create the view where the file uploader form will be placed.
Create a new file in `resources/views/files.blade.php` and place the following content:

```
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>File uploader</title>
        <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-rbsA2VBKQhggwzxH7pPCaAqO46MgnOM80zW1RWuH61DGLwZJEdK2Kadq2F9CUG65" crossorigin="anonymous">
    </head>
    <body class="antialiased">
        <div class="container">
            <div class="row">
                <div class="col-12">
                    @if ($message = Session::get('success'))
                        <div class="alert alert-success alert-dismissible fade show" role="alert">
                            <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
                            <strong>{{ $message }}</strong>
                        </div>
                    @endif
                    @if (count($errors) > 0)
                        <div class="alert alert-danger alert-dismissible fade show" role="alert">
                            <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
                            <ul class="mb-0 p-0">
                                @foreach ($errors->all() as $error)
                                    <li>{{ $error }}</li>
                                @endforeach
                            </ul>
                        </div>
                    @endif
                </div>
                <div class="col-12 py-5">
                    <div class="card my-5">
                        <div class="card-header">
                           <h3>Laravel File Uploader</h3>
                        </div>
                        <div class="card-body">
                            <form method="POST" action="{{ route('files.store')  }}" enctype="multipart/form-data">
                                @method('POST')
                                @csrf
                                <div class="mb-3">
                                    <label for="formFileLg" class="form-label">File input example</label>
                                    <input name="file" class="form-control form-control-lg" id="formFileLg"
                                           type="file">
                                </div>
                                <div class="mb-3">
                                    <button type="submit" value="submit" class="btn btn-primary">Upload</button>
                                </div>
                            </form>
                        </div>
                    </div>
                </div>
            </div>
        </div>
        <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-kenU1KFdBIe4zVF0s0G1M5b4hcpxyD9F7jL+jjXkk+Q2h455rYXK/7HAuoJl+0I4" crossorigin="anonymous"></script>
    </body>
</html>
```

This will show the form to the user to upload the files. The form in this view template is pointing to a route named `files.store` that we created earlier in `routes/web.php` file.


![Laravel upload form](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sl3omphhlp1cty6y2c7i.png)

_This is it for this tutorial._

If you need more information regarding the package used you can read more below:
{% embed https://github.com/erlandmuchasaj/laravel-file-uploader %}

## Was it helpful?

Let me know in the comment section below if you ever use this package in any of your projects.

Don’t forget to _like_ and _comment_.

Follow [me](https://twitter.com/muchasaj) for more web development tips, new packages and more.

Thanks for reading.