# Step By Step Guide To Upload Files With Laravel Framework

As a full-stack web developer, I've always needed to implement a file upload feature in my projects. Today, I'll show you how it's easy to upload files to the server with Laravel Framework.

Step 1

Let's run the following artisan command to create a controller called **FileUploadController**. This controller will be used along the tutorial to show the file upload page to the users and store the uploaded files on the server.

```javascript
php artisan make:controller FileUploadController
```

Step 2

Since we created our controller in step 1, in this step we will create a route in **web.php** to show the page to the users.

```javascript
    Route::get('/file-upload-test', [FileUploadController::class, 'index'])->name('file-upload.index');
```

Step 3

In step 2 we created a route with the URL of **file-upload-test** which calls the **index** method in **FileUploadController** to show a page to the users.

But we didn't create this method yet. So, let's create this **index** method in the **FileUploadController** which will render a blade file that we named as **file-upload.blade.php** to show the file upload page.

```javascript
<?php

namespace App\Http\Controllers;

use Illuminate\Contracts\Foundation\Application;
use Illuminate\Contracts\View\Factory;
use Illuminate\Contracts\View\View;

class FileUploadController extends Controller
{
    public function index(): Factory|View|Application
    {
        return view('file-upload');
    }
}
```

Step 4

In step 3 we created the **index** method in **FileUploadController** which renders a blade file called **file-upload.blade.php** to show the file upload page.

But we didn't create the **file-upload.blade.php** file yet. Let's create this file in the **resources/views** folder and put the following HTML into the file.

```javascript
<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>

    <style>
        .flex {
            display: flex;
        }

        .flex-col {
            flex-direction: column;
        }

        .mt-2 {
                margin-top: 20px;
        }
    </style>
</head>
<body>
    <form action="{{ route('file-upload.store') }}" enctype="multipart/form-data" method="POST">
        @csrf
        <div class="flex flex-col shadow">
            <label for="file_selector">Select a file to upload</label>
            <input type="file" id="file_selector" name="file">
        </div>

        <button type="submit" class="mt-2">Upload File</button>
    </form>
</body>
</html>
```

Once this blade file is rendered we see the following page. (If you visit **file-upload-test** URL now you will get an error, **move to the step 5**)

![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1660079461981/BBDWadKMH.png align="left")

Basically, we have a simple form with a label, an input field with the file type, and a button used to submit the form.

Let's explore the following form element a little bit to understand what's going on.

```javascript
    <form action="{{ route('file-upload.store') }}" enctype="multipart/form-data" method="POST">
        @csrf
        <div class="flex flex-col shadow">
            <label for="file_selector">Select a file to upload</label>
            <input type="file" id="file_selector" name="uploaded_file">
        </div>

        <button type="submit" class="mt-2">Upload File</button>
    </form>
```

* We need an endpoint on the form element to send the submitted data to some URL in our app. So, we put **action={{ route('file-upload.store') }}** which means that whenever the form is submitted the data will be sent to this route (we didn't create it yet).
    
* Since we are aiming to upload a file we put **enctype="multipart/form-data"** otherwise the file is not submitted to the back-end.
    
* The **method=POST** attribute is specified in the form because we are going to send a **POST** request to the endpoint.
    
* In order to pass CSRF validation on Laravel we call \*\* @csrf\*\* blade directive in the form element which creates a hidden CSRF token field.
    

Step 5

In step 4 we created an HTML form in the **file-upload.blade.php** file and now we are going to create a route named **file-upload.store** in the **web.php** file.

```javascript
    Route::get('/file-upload-test', [FileUploadController::class, 'index'])->name('file-upload.index');
    Route::post('/file-upload', [FileUploadController::class, 'store'])->name('file-upload.store');
```

Step 6

In step 5 we created a route **file-upload.store** in **web.php** and we know that the route will call **store** method in the **FileUploadController**. So, let's create this method in the controller to upload the file.

```javascript
    public function store(Request $request)
    {
        if ($request->hasFile('uploaded_file')) {
            $uploadedFile = $request->file('uploaded_file'); // the file uploaded
            $extension = $request->file('uploaded_file')->getClientOriginalExtension(); //jpg, jpeg, png
            $fileName = Str::uuid() . '.' . $extension; // de3f31db-85f8-4b9b-a3b9-a4b45b551322.jpg
            Storage::disk('public')->putFileAs('uploaded_files', $uploadedFile, $fileName);
        }

        return redirect()->back();
    }
```

Let's explore how this method work.

* First of all we check if the request has a file in the **uploaded\_file** parameter.
    
* If there is a file then we store it in the **uploadedFile** variable.
    
* Then we get the uploaded file extension using **$request-&gt;file('uploaded\_file')-&gt;getClientOriginalExtension();**
    
* We need a name to store the file in our file system. So, the **Str::uuid()** helper is used to create a universal unique identifier for the file name and appended the file extension to the end of it.
    
* There are three different disk options on Laravel as default **local, public, and s3**. Since we want to show the uploaded file in our application later we use **public** disk.
    
* In the last part, we upload the file into the **uploaded\_files** folder in the public disk (if **uploaded\_files** folder does not exist, it will be automatically created) using **Storage::disk** helper in Laravel.
    

This is how actually we upload a file in the Laravel Framework.

If you like to upload a file but also want to save the path into the database, then basically you just need to save the **fileName** variable as the path and later on, you can use this path to show the file.

Example;

```javascript
<img src="{{ asset('storage/uploaded_files/7818704d-088b-4236-b3fb-dcc15bf57cc6.jpeg') }}" alt="">
```

Note: Since we use the **public** disk of the framework we should run the following artisan command to make sure the **uploaded\_files** folder in the **storage** folder of the application is linked to the **public** as a symbolic link. Otherwise, the uploaded files will not be publicly available.

```javascript
php artisan storage:link
```
