Upload Files and Images with Validation in Laravel
Tags: laravel, php
Published: 2021-10-16 00:24:51

File upload is an essential aspect of any project. Given this importance, it is surprising that many developers face challenges of adding file upload feature to their projects. In particular, developers are unsure about how to upload and validate files.

This is a step-by-step Laravel 8 File Upload tutorial with an example, and In this tutorial, we will learn how to upload files in Laravel with Validation.

In this Laravel file upload example tutorial, we will generate two routes one for creating a form with getting method and another route for file uploading or post file upload data.

We develop a simple form using Bootstrap and its Form UI component.​

###1. Install Laravel Project
First, open Terminal and run the following command to create a fresh laravel project:
```
composer create-project --prefer-dist laravel/laravel file-upload-laravel
```
or, if you have installed the Laravel Installer as a global composer dependency:
```
laravel new file-upload-laravel
```
###2. Configure Database Details:
After, Installation Go to the project root directory, open .env file, and set database detail as follow:
```
DB_CONNECTION=mysql 
DB_HOST=127.0.0.1 
DB_PORT=3306 
DB_DATABASE=<DATABASE NAME>
DB_USERNAME=<DATABASE USERNAME>
DB_PASSWORD=<DATABASE PASSWORD>
```
###3. Create Model and Configure Migration
```
php artisan make:model File -m
```
Create a Model in laravel, It holds the data definition that interacts with the database.
open that created file which will created on database/migrations folder. just open it and put the following code into that migration file.
```
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateFilesTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('files', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->string('file');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('files');
    }
}
```
Next, migrate the table using the below command:
```
php artisan migrate
```
Now, add the $fillable property in the File model.
```
namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;


class File extends Model
{
    use HasFactory;
    protected $fillable = [
        'file'
    ];
}
```
###4. Create File Controller
Now, you need to create a controller name FileController. Use the below command and create a Controller:
```
php artisan make:controller FileController
```
Next, let’s add a method in FileController.php which is located under the app/Http/Controllers folder.

The first method renders the view via FileUpload controller, and the store() method checks the validation, be it required, mime type, or file size limitation. This method also stores the file into the storage/public/files folder and saves the file name and path in the database.
```
namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\File;

class FileController extends Controller
{
    public function index(){
        return view('fileUpload');
    }

    public function store(Request $request){
        $request->validate([
            'file' => 'required|mimes:png,jpg,jpeg|max:2048'
        ]);

        try{
            $name = now()->timestamp.".{$request->file->getClientOriginalName()}";
            $path = $req->file('file')->storeAs('files', $name, 'public');

            File::create([
                'file'=> "/storage/{$path}"
            ]);

            return redirect()->back()->with('success','File Upload Successfully!!');
        }catch(\Exception $e){
            return redirect()->back()->with('error','Something goes wrong while uploading file!');
        }
    }
}
```
###5. Create Routes
Go to routes/web.php and create two routes. First, the route handles the form creation, and the second route stores the file in the MySQL database.
```
Route::get('/file', [FileController::class, 'index']);
Route::post('/file', [FileController::class, 'store'])->name('file');
```
###6. Create Blade File
In this step, you need to create a blade view file. Go to resources/views and create one file name fileUpload.blade.php:
```
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Laravel File Upload Tutorial</title>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.3/css/bootstrap.min.css" />
</head>
<body>
    <div class="container">
    <div class="row justify-content-center">
        <div class="card">
        <div class="card-header">Laravel Upload File Example</div>
                <div class="card-body">
                    @if ($message = Session::get('success'))
                        <div class="alert alert-success alert-block">
                            <button type="button" class="close" data-dismiss="alert">×</button>
                            <strong>{{ $message }}</strong>
                        </div>
                    @endif

                    @if ($message = Session::get('error'))
                        <div class="alert alert-success alert-block">
                            <button type="button" class="close" data-dismiss="alert">×</button>
                            <strong>{{ $message }}</strong>
                        </div>
                    @endif
        
                    @if (count($errors) > 0)
                        <div class="alert alert-danger">
                            <strong>Whoops!</strong> There were some problems with your input.<br><br>
                            <ul>
                                @foreach ($errors->all() as $error)
                                    <li>{{ $error }}</li>
                                @endforeach
                            </ul>
                        </div>
                    @endif
        
                    <form action="{{ route('file') }}" method="post" enctype="multipart/form-data">
                        @csrf
                        <div class="form-group">
                            <input type="file" class="form-control-file" name="file" id="file">
                            <small class="form-text text-muted">Please upload a valid image file. Size of image should not be more than 2MB.</small>
                        </div>
                        <button type="submit" class="btn btn-primary">Submit</button>
                    </form>
                </div>
            </div>
        </div>
    </div>
</html>
```
Before starting the application you need to run this command to access all uploaded images ignore this command if you don't upload in a public disk.
```
php artisan storage:link
```

The public disk is intended for files that are going to be publicly accessible. By default, the public disk uses the local driver and stores these files in storage/app/public. To make them accessible from the web, you should create a symbolic link from public/storage to storage/app/public.

###Start Laravel Application
execute the following command.
```
php artisan serve
```
Thank you for reading this blog.