Vaidikalaya

Multiple Images Upload In Laravel

In this tutorial, we will learn how to upload multiple images in the Laravel applications with validation. So first, we create Laravel app and add logic for uploading multiple images together.


STEP 1: Create Laravel app
laravel new laravel-multiple-images-upload

STEP 2: Go to the project directory
cd new laravel-multiple-images-upload

STEP 3: Create a Controller
php  artisan make:controller ImagesController

STEP 4: Write code for image upload

Go to your App\Http\Controllers\ImagesController and create a method (uploadImage) and write code in it for uploading images. In this method first, we validate all images if all images are validated then we upload them to a public directory and store their paths in the $imageURL array

<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;

class ImagesController extends Controller
{
    public function uploadImage(Request $request){
        $test=$request->validate([
            'images' => 'required',
            'images.*' => 'mimes:png,jpg,jpeg|max:2048'
        ],[
            'images.*.required' => 'Please upload an image',
            'images.*.mimes' => 'Only jpeg,png images are allowed',
            'images.*.max' => 'Sorry! Maximum allowed size for an image is 2MB',
        ]);

        try{
            $imagesURL=[]; // it is tempary  array where we save path of uploaded images
            $uploaded_path=public_path('uploads/images/'); // this is path where we upload our images
            foreach($request->images as $image){
                $image_name=time().'-'.$image->getClientOriginalName();
                $image->move($uploaded_path,$image_name);
                $img_path=asset('uploads/images/'.$image_name);
                array_push($imagesURL,$img_path);
            }
            return back()->with('success_msg','images uploaded successfully')
                        ->with('uploaded_img',$imagesURL);
        }
        catch(Exception $e){
            return $e;
        }
    }
}

OR You can validate images like this

The previous validation rule sends an error message individually for all images but if you want to send only one message for all images then apply the validation rule given below.

<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;

class ImagesController extends Controller
{
    public function uploadImage(Request $request){

        $validator=Validator::make($request->all(),[
            'images' => 'required',
            'images.*' => 'mimes:png,jpg,jpeg|max:2048'
     ]);

        if($validator->fails()) {
            return back()->with('error_msg', 'all images must be type of jgp or png and max size 2mb');
     }

        try{
            $imagesURL=[];
            $uploaded_path=public_path('uploads/images/');
            foreach($request->images as $image){
                $image_name=time().'-'.$image->getClientOriginalName();
                $image->move($uploaded_path,$image_name);
                $img_path=asset('uploads/images/'.$image_name);
                array_push($imagesURL,$img_path);
        }
            return back()->with('success_msg','images uploaded successfully')
                        ->with('uploaded_img',$imagesURL);
        }
        catch(Exception $e){
            return $e;
        }
    }
}

STEP 5: Setup blade file (welcome.blade.php)
<!DOCTYPE html>
<html lang="en">
<head>
    <title>Laravel Image Upload</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css" rel="stylesheet">
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.bundle.min.js"></script>
</head>
<body>

    <div class="container d-flex mt-5">
        <div class="card">
            <div class="card-body">
                <form action="/upload-image" method="post" enctype="multipart/form-data">
                    @csrf
                    @if(count($errors)>0)
                        @foreach ($errors->all() as $error)
                            <div class="alert alert-danger show">{{ $error }}</div>
                        @endforeach
                    @endif
                    {{-- if you implement second validation then uncomment it
            @if(session('error_msg'))
                  <div class="alert alert-danger show">{{ session('error_msg') }}</div>
            @endif
        --}}
                    <input type="file" name="images[]" class="form-control" multiple required>
                    <button class="btn btn-primary mt-2">Upload</button>
                </form>
            </div>

            @if(session('success_msg'))
                <div class="card-footer">
                    <div class="alert alert-success show">{{ session('success_msg') }}</div>
                    @if(count(session('uploaded_img'))>0)
                        @foreach(session('uploaded_img') as $imageURL)
                            <img src="{{$imageURL}}" height="50px" width="50px">
                        @endforeach
                    @endif
                </div>
        @endif
   
        </div>
    </div>
</body>
</html>

STEP 6: Set routes (web.php)
<?php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\{ImagesController};

Route::get('/', function () {
    return view('welcome');
});

Route::post('/upload-image',[ImagesController::class,'uploadImage']);

OUTPUT