Ranjeet's avatar

How to upload different image to their respective column in DB

Iam having a problem to upload 3 images the their three column namely image1,image2,image3.

my Model is like this

<?php namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Product extends Model {
   protected $table = 'products';

    protected $fillable = ['image1','image2','image3'];
}

my form

{!! Form::open(['action' => 'Product\ImageController@multpleImageUpload', 'method' => 'POST','files'=>true]) !!}

{!! Form::label('file1', 'Select file 1', ['class' => 'control-label']) !!}
            {!! Form::file('file1', ['id'=>'file1']) !!}
        <br>
            {!! Form::label('file2', 'Select file 2', ['class' => 'control-label']) !!}
            {!! Form::file('file2', ['id'=>'file2']) !!}
       <br>
       
            {!! Form::label('file3', 'Select file 3', ['class' => 'control-label']) !!}
            {!! Form::file('file3', ['id'=>'file3']) !!}
            <br>

 {!!Form::submit('Submit',array('class'=>'btn btn-success','id'=>'send'))!!}

{!!Form::close()!!}

my controller

 public function multpleImageUpload(Request $request)
    {

        $save = new product;    
        $files =[];
        if ($request->file('file1')) $files[] = $request->file('file1');
        if ($request->file('file2')) $files[] = $request->file('file2');
        if ($request->file('file3')) $files[] = $request->file('file3');
        foreach ($files as $file)
        {
          if(!empty($file)){
            $filename[] = $file->getClientOriginalName();
            $file->move(
                base_path().'/public/uploads/', $filename
            );
        $save->image1 = $filename;
        $save->image2 = $filename;
        $save->image3 = $filename;
        $save->save();

        }

    }

}

it upload 3 different image to folder,if i browse 3 different images. But it saves only one image name in database column image1,image2,image3.it save same image name to three column.why?

0 likes
11 replies
MikkoPEL's avatar

Try something like

foreach ($files as $file) {
    if(!empty($file)){
        $filenames[] = $file->getClientOriginalName();
        $file->move(base_path().'/public/uploads/', end($filenames));
    }
}

$save->image1 = $filenames[0];
$save->image2 = $filenames[1];
$save->image3 = $filenames[2];
$save->save();
1 like
MikkoPEL's avatar

$filenames is an array. On the previous line you insert the file name in to the array, making it the last element in it. The end function returns the last element in an array.

1 like
Ranjeet's avatar

@MikkoPEL how to upload multiple images to same column name of database?how will be form and controller looks like

MikkoPEL's avatar

Then you need to remove the following lines

$save->image1 = $filenames[0];
$save->image2 = $filenames[1];
$save->image3 = $filenames[2];

and instead use

$save->image = join(",", $filenames):
Ranjeet's avatar

@MikkoPEL iam unable to upload images neither in folder nor in db when i mixed some code in above code

$status = new product;
              $status->name=$request->get('name');
              $status->cat_id=$request->get('cat_id');
              $status->tags=$request->get('tags');
              $status->vehicle=implode(',',$request->get('vehicle'));
              
              $files=[];
              if ($request->file('file1')) $files[] = $request->file('file1');
              if ($request->file('file2')) $files[] = $request->file('file2');
              if ($request->file('file3')) $files[] = $request->file('file3');
              foreach ($files as $file) {
              if(!empty($file)){
                if(isset($filenames)){
                  $filenames[] = $file->getClientOriginalName();
                  $file->move(base_path().'/public/uploads/', end($filenames));
              }
            }

              $status->image1 = $filenames[0];
              $status->image2 = $filenames[1];
              $status->image3 = $filenames[2];
              $status->save();

     }

i got no error but no nothing is saved in database

MikkoPEL's avatar
$product = new product;
$product->name = $request->get('name');
$product->cat_id = $request->get('cat_id');
$product->tags = $request->get('tags');
$product->vehicle = implode(',', $request->get('vehicle'));

$files = [];

if($request->file('file1')) 
    $files[] = $request->file('file1');
if($request->file('file2')) 
    $files[] = $request->file('file2');
if($request->file('file3')) 
    $files[] = $request->file('file3');

foreach ($files as $file) {
    if(!empty($file)) {
        $filenames[] = $file->getClientOriginalName();
        $file->move(base_path() . '/public/uploads/', end($filenames));
    }
}

$product->image1 = $filenames[0];
$product->image2 = $filenames[1];
$product->image3 = $filenames[2];
$product->save();

A few notices:

  • You have no validation. Anyone can upload anything, not just images.
  • You are limited to three images because you have three separate columns in the database. Maybe have a table for just images and save product_id in that table to reference the images?
  • If the user uploads less than three images, accessing the array with static indexes will cause a warning.

So I'd suggest something like this:

Remove the image1, image2 and image3 columns from the Product table. Create a new relationship:

<?php namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Product extends Model {
    protected $table = 'products';

    public function images() {
        return $this->hasMany("App\Models\Image");
    }
}

The new Image model:

<?php namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Image extends Model {
    protected $table = 'images';

    public function product() {
        return $this->belongsTo("App\Models\Product");
    }
}

Insert the product images like this:

<?php

$product = new Product;

// TODO Get images

foreach($uploadedImages as $upload) {
    // TODO Check if the uploaded file is valid
    
    // Save the uploaded image path to the database
    $image = new Image;
    $image->url = $upload->getClientOriginalName();

    // TODO Copy the uploaded image to the destination directory

    $product->images()->save($image);
}

$product->save();

Of course, if you are just beginning with Laravel, don't bother with this. You will eventually learn why this approach is better and how it works. If you want to learn more about these relationships, look here:

http://laravel.com/docs/5.1/eloquent-relationships#one-to-many

2 likes
Ranjeet's avatar

yes i know about relationship,but my above code in not working why? ,if i remove the all upload code then it works fine

anam's avatar

Check this:

public function multpleImageUpload(Request $request)
{
    $save = new product;

    $files = [];

    if ($request->hasFile('file1')) $files[] = $request->file('file1');
    if ($request->hasFile('file2')) $files[] = $request->file('file2');
    if ($request->hasFile('file3')) $files[] = $request->file('file3');
    
    $i = 1;

    foreach ($files as $file) {         
        $filename = $file->getClientOriginalName();
        $file->move(base_path().'/public/uploads/', $filename);
    
        $save->{"image" . $i} = $filename;
        
        $save->save();

        $i++;
    }
}
2 likes
Snapey's avatar

what is the purpose of if (isset($filenames)) ?

this probably just skips every loop

but why have a loop at all? You could do what you want much simpler just by repeating three simple sections. Just get the filename, write it to the database column, move the file. Writing it to an array and then immediately reading back out is a needless distraction.

Once you have that working you can refactor into a loop where the image number and column name are dynamic

luddinus's avatar

I'm not sure but, is possible to call "files[]" to the input files?

<input type="file" name="files[]">
<input type="file" name="files[]">
<input type="file" name="files[]">

And then

public function uploadFiles(Request $request)
{
   $files = $request->file('files[]'); // array of files?
}

Just asking.

gnack's avatar

@snapey is correct - your if statement: if (isset($filenames)) will never return true, so the files will never get uploaded and your filenames array will be empty. I'm actually surprised you didn't get an error when you tried to use it here: $status->image1 = $filenames[0];

As a side-note, Jeff any chance we'll get quote functionality at some stage? :)

Please or to participate in this conversation.