How to upload multiple files at one go in Php Laravel?

How to upload multiple files at one go in Laravel

I was recently working on an Laravel Project where there were galleries in which, the user can login and add images. It was pretty simple and all was fine.

Then, after a while, the client came back with a change in the current reqirement. Now, they wanted to select and upload multiple images on the Laravel website back-end. Thankfully, I had kind of forseen this coming and had kept this in mind while designing the database architecture.

Multiple Image Upload on Laravel Website

The first step of uploading and storing multiple images at once, in the approach I used, was to not store the image data in the gallery table itself. Instead, what I did was, before uploading multiple images and then saving them in the MySql database (which was at the backend for this project), I made selecting the Gallery in which they will be associated, mandatory. This is how my upload multiple images form looked like.

This is how my image(s) upload form looks

The one important thing to enable multiple file uploads is to set the multiple attribuite to the input control. The control should look like this:

<input type="file" class="form-control form-control-file" id="gallery-image" value="{{ old('gallery-image') }}" required name="gallery-image[]" multiple/>

Also the other thing to note is that I save all the images in a loop. In order to access the individual images, the name has to be an array. More about that later. For now, here’s the full frontend code of the form up the multi-image upload module.

<form class="form-horizontal staff-member-add" method="POST" action="/dashboard/member/galleryimages" enctype='multipart/form-data'>
                            @csrf
                            <div class="card-body">
                                <div class="form-group row">
                                    <label for="gallery-id" class="col-sm-3 text-left control-label col-form-label">Choose Gallery</label>
                                    <div class="col-sm-9">
                                        @if($galleries)
                                            <select class="form-control" name="gallery-id" id="gallery-id" required>
                                                @foreach ($galleries as $gallery)
                                                    <option value="{{$gallery->id}}">{{$gallery->gallery_name}}</option>
                                                @endforeach
                                            </select>
                                        @else
                                            <select class="form-control" name="gallery-id" id="gallery-id" required>
                                                <option value="-1">NO GALLERIES - Create a Gallery first to add images</option>
                                            </select>
                                        @endif
                                        
                                    </div>
                                </div>
                                
                                <div class="form-group row">
                                    <label for="gallery-image" class="col-sm-3 text-left control-label col-form-label">Photo</label>
                                    <div class="col-md-9">
                                        {{-- <input type="file" name="images[]" multiple> --}}
                                        <input type="file" class="form-control form-control-file"
                                         id="gallery-image" value="{{ old('gallery-image') }}" required name="gallery-image[]" multiple/>
                                         <span class="below-image-upload-msg">Recommended image dimension: 800 x 700 pixels. File size should be less than 2Mb.</span>
                                    </div>
                                    @error('image')
                                    <span class="invalid-feedback" role="alert">
                                        <strong>{{ $message }}</strong>
                                    </span>
                                    @enderror
                                </div>

                                {{-- <div class="form-group row">
                                    <label for="photo-caption" class="col-sm-3 text-left control-label col-form-label">Photo caption</label>
                                    <div class="col-sm-9">
                                        <input type="text" class="form-control photo-caption" name="photo-caption" id="photo-caption" 
                                        placeholder="Add image caption">
                                    </div>
                                </div> --}}
                            </div>
                            <div class="border-top">
                                <div class="card-body">
                                    <button type="submit" class="btn btn-warning btn-add-to-gallery">Add to Gallery</button>
                                </div>
                            </div>
                        </form>

Saving multiple image files in a loop – Laravel

The store function that uploads multiple images on the server and also saves the file names in the database table is implemented in this way:

public function store(Request $request){
        $validation = Validator::make($request->all(), array(
            'gallery-id'    => 'required|integer|min:0',
            'gallery-image' => 'required|image|nullable|mimes:jpeg,png,jpg,gif|max:2048',
        ));
        $fileNameToStore="no-image.jpg";

        if(request('gallery-image'))
		{
            $i=0;
            foreach($request->file('gallery-image') as $thisImage){
                $fileNameWithExtension = $thisImage->getClientOriginalName();
                $memberNameFolder = 'fileName';

                $extension=$thisImage->getClientOriginalExtension();
                
                $fileNameToStore = $fileName.'_'.time().$i.'.'.$extension;

                $path= $thisImage->storeAs('public/images/members/'.$memberNameFolder.'/gallery-images',$fileNameToStore);


                $isEnabled                                   = "0";                      //Default - no news item goes to the homepage
                $galleryImage                                = new GalleryImage();
                $galleryImage->gallery_id                    = request('gallery-id');
                $galleryImage->gallery_image_caption         = " ";//request('photo-caption');
                $galleryImage->gallery_image                 = $fileNameToStore;

                $galleryImage->save();
                $i++;
            }
            return redirect('/dashboard/member/galleryimage/create')->with('success', 'Image(s) successfully added to gallery!');
        }
    }

All that the above code does is, it checks if atleast one file was selected. If more than one file was selected for upload, it starts looping through the list of files and then generates a filename for every image, uploads them to a server location and then saves the file name to the database.

How to select only images while uploading multiple files?

In order to limit our multiple file uploads to show only image files, I changed the code slightly. The new code for uploading only image multiple files now looks like this:

<input type="file" class="form-control form-control-file" id="gallery-image" value="{{ old('gallery-image') }}" required name="gallery-image[]" multiple accept="image/*"/>

So, all I did here was added accept=”image/*”.

Remember that it is an HTML5 directive so, old browsers might not recognise it.

Also, always check the uploaded file type on the server side, just to be sure.

That’s all.

Hope this helps.

Share This Post

Subscribe To my Future Posts

Get notified whenever I post something new

More To Explore

How To Use Google SIgn In In Flutter
Blog

How To Use Google Sign In Flutter?

This topic is divided into 2 parts. The parts are as follows: 1 – Creating a Firebase Project 2 – Configuring the Flutter app and