How to Upload File in Laravel 8 with Validation | Laravel File Uploading into Database Tutorial

Throughout this tutorial, you will learn how to upload a file in the Laravel application; additionally, you will use the Bootstrap CSS framework to design and create the file uploading module besides we will also unveil how to validate a file and upload to a database using a local development server MAMP or XAMPP.

Creating a feature to upload a file is a common task for any web developer; millions of photos, videos and documents daily updated to various websites. Consequently, this tutorial will help you understand the file uploading and validating concept in the laravel application step by step.

In this tutorial we are throwing light on these concepts:

  • Setting database
  • Validate file uploading before the file upload
  • Display message on file uploading progress
  • Restrict file type to.csv, .txt, .xlx, .xls, .pdf
  • Set file size limitation
  • Save file inside the database and public folder

Create Laravel Application

Start with creating a Laravel application.

composer create-project laravel/laravel --prefer-dist laravel-file-upload-example

Adding Database Details

Add database name, username and password within the .env file:

DB_CONNECTION=mysql
DB_HOST=localhost
DB_PORT=3306
DB_DATABASE=db
DB_USERNAME=root
DB_PASSWORD=

Create Model and Run Migrations

You need to create a table in database and define the schema for uploading a file, In addition generate a model in your laravel application:

php artisan make:model Product -m

Define Product values in database/migrations/timestamp_create_products_table.php these values will be used for uploading image:

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

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

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('products');
    }
}

On the other hand, define the $fillable array and table properties in app/File.php:

<?php

namespace App\Models;

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

class Product extends Model
{
    use HasFactory;
    protected $fillable = [
        'name',
        'file'
    ];    
}

Head over to console and run the migration:

php artisan migrate

Create & Setting Up Controller

So as to upload a file or image, you need to generate a controller; consequently, you can define the logic to validate and upload the file into the database through view:

php artisan make:controller UploadController

Define the given below code in Open app/Http/Controllers/UploadController.php:

<?php

namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\Product;


class UploadController extends Controller
{
    public function index(){
        return view('welcome');
      }
    
      public function uploadFile(Request $request){
            $request->validate([
            'file' => 'required|mimes:png,jpg,jpeg,csv,txt,xlx,xls,pdf|max:2048'
            ]);
    
            $file = new Product;
    
            if($request->file()) {
                $name = time().'_'.$request->file->getClientOriginalName();
                $filePath = $request->file('file')->storeAs('uploads', $name, 'public');
    
                $file->name = time().'_'.$request->file->getClientOriginalName();
                $file->file = '/storage/' . $filePath;
                $file->save();
    
                return back()
                ->with('success','File has uploaded to the database.')
                ->with('file', $name);
            }
       }
}

Create Routes

Define two routes simultaneously one for invoking view other one for making POST request to upload file in routes/web.php:

<?php

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

/*
|--------------------------------------------------------------------------
| 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::get('upload', [UploadController::class, 'index']);

Route::get('upload', [UploadController::class, 'uploadFile'])->name('upload-file');

Create Blade View

Add given below code in resources\views\welcome.blade.php to initialize the view:

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

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css">

    <title>Laravel File Upload</title>
    <style>
        .container {
            max-width: 450px;
        }
        dl, ol, ul {
            margin: 0;
            padding: 0;
            list-style: none;
        }
    </style>
</head>

<body>

    <div class="container mt-5">
        <form action="{{route('upload-file')}}" method="post" enctype="multipart/form-data">
            @csrf
            @if ($msg = Session::get('success'))
            <div class="alert alert-success">
                <strong>{{ $msg }}</strong>
            </div>
          @endif

          @if (count($errors) > 0)
            <div class="alert alert-danger">
                <ul>
                    @foreach ($errors->all() as $error)
                      <li>{{ $error }}</li>
                    @endforeach
                </ul>
            </div>
          @endif

            <div class="custom-file">
                <input type="file" name="file" class="custom-file-input" id="chooseFile">
                <label class="custom-file-label" for="chooseFile">Choose file</label>
            </div>

            <button type="submit" name="submit" class="btn btn-primary btn-block mt-4">
                Upload Files
            </button>
        </form>
    </div>

</body>
</html>

Test File Uploading

Start the application:

php artisan serve

Check the app on the following path:

http://127.0.0.1:8000/upload

Summary

We have developed the essential file uploading feature in the Laravel application and successfully stored it in the MySQL database. Additionally, we saw how to validate the file and set the file upload limit for size; I hope you would like this intuitive tutorial.