Laravel 8 Multiple Images Upload with Validation Example

  18969 views   1 year ago Laravel

File uploading is basic feature in any web application. File uploading should be properly validated from backend server before saving data.

In this article, we will create a Laravel application with multiple image files upload tutorial. We will set multiple validations for images files, e.g., file extensions, size etc. and error messages in blade view. After images and databases saved, we will show them on blade.

We will go step by step from the scratch. So let's start from creating new Laravel application.

Step 1: Create a new Laravel application

In the first step, we will create new Laravel application. So first open Terminal and run the following composer command to create a fresh Laravel application.

composer create-project laravel/laravel image-upload

After project created, change working directory to project directory

cd image-upload

Step 2: Configure database

Open Laravel project to your favourite text editor. Now open .env file from the root directory and change database credentials from your mysql.

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=images
DB_USERNAME=root
DB_PASSWORD=root

Step 3: Create migration

In the third step, we create a migration for table in which we will save image files path. To create a migration, run the following command into Terminal.

php artisan make:migration create_posts_table

This will create a migration file into /database/migrations directory. Open the file and add below code into migrations up() method.

<?php

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

class CreatePostsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('posts', function (Blueprint $table) {
            $table->id();
            $table->string('title');
            $table->text('images');
            $table->timestamps();
        });
    }

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

And run migrate command to create a posts table into database.

php artisan migrate

Step 4: Create Post model

We will need to create model class for posts table. The application will communicate with MySQL database using model class. So run the below artisan command to generate model class.

php artisan make:model Post

This will create a model class at app/models/Post.php file. Open the file and add $fillable attribute. This attribute is required to protected against mass assignment vulnerabilities.

<?php

namespace App\Models;

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

class Post extends Model
{
    use HasFactory;

    /**
     * The fillable attribute to allow fields mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'title',
        'images'
    ];
}

Step 5: Create ImageController class

In this step, we will create controller class and add image upload logic. To create controller class, we use following artisan command:

php artisan make:controller ImageController

This will create controller class at app/Http/Controllers/ImageController.php file. Open the file and add form() and upload() two methods in it.

<?php

namespace App\Http\Controllers;

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

class ImageController extends Controller
{
    /**
     * images upload form view
     *
     * @return \Illuminate\Http\Response
     */
    public function form()
    {
        return view('form');
    }

    /**
     * upload images
     *
     * @return \Illuminate\Http\Response
     */
    public function upload(Request $request)
    {
        // validate image and title
        $validated = $request->validate([
            'title' => 'required',
            'images.*' => 'required|image|mimes:jpg,jpeg,png,gif|max:2048',
        ]);

        $image_names = [];
        // loop through images and save to /uploads directory
        foreach ($request->file('images') as $image) {
            $name = $image->getClientOriginalName();
            $image->move(public_path().'/uploads/', $name);  
            $image_names[] = $name;
        }

        $post = new Post();
        $post->title = $request->title;
        $post->images = json_encode($image_names);

        $post->save();

        return redirect()
            ->back()
            ->with('success', 'Post created successfully.');
    }
}

To save images path into database, we used json array instead of seperate table for image path. This way, we don't need to join tables to get image path.

We have also validated image size to maximum 2MB with specific extensions only.

Step 6: Create routes

We have created controller and created methods into it. We need to create two routes for these methods. Routes are located into routes directory. Open routes.web.php file and add two new routes. Don't forget to use controller before routes.

<?php

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

Route::get('image', [ImageController::class, 'form'])->name('form');
Route::post('upload', [ImageController::class, 'upload'])->name('upload');

Step 7: Create form blade view

The first method will return the form view. Laravel views are stored at resources/views directory. Create a view file form.blade.php and add the below HTML code into it.

<!doctype html>
<html>
<head>
    <meta charset="utf-8">
    <title>Multiple image upload</title>
    <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
    <div class="container m-5">
        <h1>Multiple image upload</h1>
        <div class="row">
            <div class="col-9">
                @if (\Session::has('success'))
                    <div class="alert alert-success">
                        <strong>{{ \Session::get('success') }}</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
                <form method="post" action="{{ route('upload') }}" enctype="multipart/form-data">
                    @csrf
                    <div class="mb-3">
                        <label for="title" class="form-label">Title</label>
                        <input type="text" class="form-control" id="title" placeholder="title" name="title" value="{{ old('title') }}">
                    </div>
                    <div class="mb-3">
                        <label for="images" class="form-label">Select images</label>
                        <input class="form-control" type="file" id="images" name="images[]" multiple>
                    </div>
                    <input type="submit" class="btn btn-primary">
                </form>
            </div>
        </div>
    </div>
</body>
</html>

Our coding part we have done. Now run the Laravel application server using following command.

php artisan serve

In your browser, open the url http://localhost:8000/image and try to upload files using different extensions and sizes. You will see the validation errors.

That's our tutorial is completed. So far we have learned how to validate and upload multiple images by extensions and size. We have also learned how to save multiple images path into database using json array.

I hope you liked this tutorial article.

Author : Harsukh Makwana
Harsukh Makwana

Hi, My name is Harsukh Makwana. i have been work with many programming language like php, python, javascript, node, react, anguler, etc.. since last 5 year. if you have any issue or want me hire then contact me on [email protected]