Seeker1337's avatar

Laravel 6+ Upload multiple images through a form

Hello. Basically I have a form that stores some information and an image in a MySql database. However, I have to change this to taking up to multiple images. I've tried looping through them with @foreach but can't get it working. Some help would be appreciated. Here is my code:

VehiclesModel.php


class VehiclesModel extends Model
{
    protected $table = 'vehs' ;
    protected $fillable = [
        
      'vehmod', 'vehmark', 'vehyear', 'vehengine', 'vehtrans', 'vehimage' 
        
    ] ; 
}


VehiclesController.php

use App\VehiclesModel ;

   public function store(Request $request)
    {
        
        $vehiclesmodel = new VehiclesModel ;
        $vehiclesmodel->vehmod = $request->vehmod ;
        $vehiclesmodel->vehmark = $request->vehmark ;
        $vehiclesmodel->vehyear = $request->vehyear ;
        $vehiclesmodel->vehengine = $request->vehengine ;
        $vehiclesmodel->vehtrans = $request->vehtrans ;
        $vehiclesmodel->vehimage = $request->vehimage ;
        
        $file = $vehiclesmodel->vehimage = $request->vehimage ;
 // ---Somewhere here I have to declare vehimage as an array and loop through it ---

        $filename = $file->getClientOriginalName() ;
        $destinationPath = 'storage/veh-images' ; 
        $vehiclesmodel->vehimage = $filename; 
        $uploadSuccess = $file->move($destinationPath, $filename);
        
        $vehiclesmodel->save() ;

        return redirect('mypage')->with('success', 'The record has been added succesfully!') ;
    }

VehiclesForm.blade.php


<form action="{{ route('mypage.store') }}" method="post" enctype="multipart/form-data">
      @CSRF
        <div class="form-group">
        <label for="text">Model:</label>
        <input type="text" class="form-control" name="vehmod" placeholder="Insert the model of the vehicle">
        </div>
      
        <div class="form-group">
        <label for="text">Mark:</label>
        <input type="text" class="form-control" name="vehmark" placeholder="Insert the mark of the vehicle">
        </div>
      
        <div class="form-group">
        <label for="number">Year:</label>
        <input type="number" class="form-control" name="vehyear" placeholder="Insert the year of the vehicle">
        </div>
      
        <div class="form-group">
        <label for="text">Engine:</label>
        <input type="text" class="form-control" name="vehengine" placeholder="Insert the engine of the vehicle">
        </div>

        <div class="form-group">
        <label for="text">Transmission:</label>
        <input type="text" class="form-control" name="vehtrans" placeholder="Insert the transmission of the vehicle">
        </div>

        <div class="form-group">
        <label for="pic">Vehicles pictures:</label> <br>
        <input type="file" name="vehimage[]" multiple>
        </div>

        <button type="submit" class="btn btn-primary">Add record</button>
  </form>

0 likes
13 replies
Snapey's avatar

$request->file will be a collection;

$files = $request->file('vehimage');

foreach($files as $file){

    //process each image
}
1 like
Sergiu17's avatar

Hi, you need a separate table to store images, One Vehicle has Many Images, then loop over them and store

$vehiclesmodel = new VehiclesModel;
// .... 
$vehiclesmodel->save();

$images = $request->vehimage; // collection

// loop over collection an store each image 
foreach($images as $image) {
    $filename = $file->getClientOriginalName();
    $destinationPath = 'storage/veh-images';

    $uploadSuccess = $file->move($destinationPath, $filename);

    $imageModel = new Image(); // this model you have to create
    $imageModel->name = $filename;
    $imageModel->vehicle_id = $vehiclesmodel->id;
    $imagemodel->save();
}

return redirect('mypage')->with('success', 'The record has been added succesfully!');
1 like
Seeker1337's avatar

Basically I need a separate table with just one field e.g 'vehgalleryimages' and loop through it? Do I also have to make controllers and so on? I kind of got confused with this one. Can't i just loop through my "vehimage" field and have an undefined amount of images?

sauravs012's avatar
Level 2

There are various methods to do this. I've used below one, in which all images are store in a cell with implode(|). You have to change column type to text if you want to store all images in single column of a row

public function store(request $request) {

    $destinationPath = 'storage/veh-images' ; 
    $images=array();
    if($files=$request->file('vehimage')){
        foreach($files as $file){
            $filename=$file->getClientOriginalName();
            $file->move($destinationPath, $filename);
            $images[]=$name;
        }
    }
    //implode images with pipe symbol
    $allImages = implode("|",$images);

    $vehiclesmodel = new VehiclesModel ;
    $vehiclesmodel->vehmod = $request->vehmod ;
    $vehiclesmodel->vehmark = $request->vehmark ;
    $vehiclesmodel->vehyear = $request->vehyear ;
    $vehiclesmodel->vehengine = $request->vehengine ;
    $vehiclesmodel->vehtrans = $request->vehtrans ;
    $vehiclesmodel->vehimage = $allImages;

    $vehiclesmodel->save() ;
    return redirect('mypage')->with('success', 'The record has been added succesfully!') ;
}

You can also try with json

2 likes
Seeker1337's avatar

Hey mate this is working so far, thank you. I'd just like to ask you one more thing:

How can I display all of the images together with other information in another page?

mypage.blade.php


<?php   

    foreach ($vehiclesmodel as $VehiclesModel) {
?>    
    
<tr> 

    <td> {{ $VehiclesModel->id }} </td>
    <td> {{ $VehiclesModel->vehmod }} </td>
    <td> {{ $VehiclesModel->vehmark }} </td>
    <td> {{ $VehiclesModel->vehyear }} </td>
    <td> {{ $VehiclesModel->vehengine }} </td>
    <td> {{ $VehiclesModel->vehtrans }} </td>

    <td> 
        <img src="storage/veh-images/{{ $VehiclesModel->vehimage }}" height="50px" width="30%">
    </td>
 
</tr>
 
<?php  }    ?>

Snapey's avatar

Just use Spatie Media Library, it takes care of multiple images attached to a single model

Seeker1337's avatar

And I can loop through them or? Never used it.

SinghWithLaravel's avatar

@seeker1337 Yeah, you can loop through the images. In that case you will have to explode it from comma like below code. -

<?php   

    foreach ($vehiclesmodel as $VehiclesModel) {
    $allImages = explode("|",$images);

?>    
    
<tr> 

    <td> {{ $VehiclesModel->id }} </td>
    <td> {{ $VehiclesModel->vehmod }} </td>
    <td> {{ $VehiclesModel->vehmark }} </td>
    <td> {{ $VehiclesModel->vehyear }} </td>
    <td> {{ $VehiclesModel->vehengine }} </td>
    <td> {{ $VehiclesModel->vehtrans }} </td>
    <td> 
    @php
        @foreach($allImages as $image)
                <img src="storage/veh-images/{{$image}}" height="50px" width="30%">
        @endforeach
    @endphp
    </td>
 
</tr>
 
<?php  }    ?>
Seeker1337's avatar

I'm getting the error Undefined variable: vehimages in the file mypage.blade.php at this line: -- $allImages = explode("|",$vehimages); --

VehController.php -STORE- method

public function store(Request $request)
    {
        $destinationPath = 'storage/veh-images' ;
        $vehimages = array() ;
        
        if($files=$request->file('vehimages')) {
            
        foreach($files as $file) {
            
            $filename = $file->getClientOriginalName() ;
            $file->move($destinationPath, $filename) ;
            $vehimages[] = $filename;
          }
        }
        //implode images with pipe symbol
        $allImages = implode("|",$vehimages) ;
        
        $vehichlesmodel = new VehiclesModel ;
        
        $vehichlesmodel->vehmod = $request->vehmod ;
        $vehichlesmodel->vehmark = $request->vehmark ;
        $vehichlesmodel->vehyear = $request->vehyear ;
        $vehichlesmodel->vehengine = $request->vehengine ;
        $vehichlesmodel->vehtrans = $vehtrans ;
        $vehichlesmodel->vehimages = $allImages ;
        
        $vehichlesmodel->save() ;
        
         return redirect('mypage')->with('success', 'etc..') ;

        }     

mypage.blade.php

<?php   

    foreach ($vehiclesmodel as $VehiclesModel) {
    $allImages = explode("|",$vehimages);

?>    
    
<tr> 

    <td> {{ $VehiclesModel->id }} </td>
    <td> {{ $VehiclesModel->vehmod }} </td>
    <td> {{ $VehiclesModel->vehmark }} </td>
    <td> {{ $VehiclesModel->vehyear }} </td>
    <td> {{ $VehiclesModel->vehengine }} </td>
    <td> {{ $VehiclesModel->vehtrans }} </td>
    <td> 
    @php
        @foreach($allImages as $vehimages)
                <img src="storage/veh-images/{{$vehimages}}" height="50px" width="30%">
        @endforeach
    @endphp
    </td>
 
</tr>
 
<?php  }    ?>

SinghWithLaravel's avatar

@seeker1337 Change $allImages = explode("|",$vehimages); like below line -

$allImages = explode("|",$VehiclesModel->vehimages);

1 like
Seeker1337's avatar

Its working now, great job mate. Thank you very much.

Please or to participate in this conversation.