fikri1510's avatar

Only first images path saved to database

I am uploading multiple images to storage and saving their paths into db. It works, it stores all image intu folder but only first path of image saved into db. I am trying what the problem was, but I could not figure it out. So please help me. Here is the form

<form action="{{ route('store') }}" method="POST" enctype="multipart/form-data">
   @csrf
   <div class="form-group">
      <label>Upload your file</label>
      <input type="file" name="preview[]" multiple />
   </div>
   <br />
   <button type="submit" class="btn btn-info">Submit</button>
</form>

and controller

public function store(Request $request) {
        $destinationPath = 'uploads/';
        request()->validate([
            'preview.*' => 'required|image|mimes:jpeg,png,jpg,gif,svg|max:2048',
        ]);
        $image = new Multi;
        $files = $request->file('preview');
        foreach ($files as $file) {
            $filename = $file->getClientOriginalName();
            $file->move($destinationPath, $filename);   
            $image->preview = $destinationPath.$filename;
        }

        $image->save();

        return back()->with('success', 'Preview Upload successfully');
 }
0 likes
7 replies
MichalOravec's avatar

Yes, because in the foreach loop you everytime replace it. So change it to this

public function store(Request $request)
{
    $request->validate([
        'preview.*' => 'required|image|mimes:jpeg,png,jpg,gif,svg|max:2048'
    ]);

    $destinationPath = 'uploads/';
    
    foreach ($request->file('preview') as $file) {
        $image = new Multi;

        $filename = $file->getClientOriginalName();
        
        $file->move($destinationPath, $filename);   
        
        $image->preview = $destinationPath.$filename;

        $image->save();
    }

    return back()->with('success', 'Preview Upload successfully');
 }
fikri1510's avatar

Thanks for reply, I tried your code. Strangely, it is still the same. Thanks anyway!

fikri1510's avatar

I ended up with this solution, I think it is ugly but it works. Any better suggestion?

 $destinationPath = 'uploads/';
        request()->validate([
            'preview.*' => 'required|image|mimes:jpeg,png,jpg,gif,svg|max:2048',
        ]);

        $image = new Multi;
        $file = $request->file('preview');
        $temp = array();

        for ($i = 0; $i < 10; $i++) { //maximum user can upload up to 10 files
            $filename[$i] = $file[$i]->getClientOriginalName();
            $temp[] = $file[$i]->move($destinationPath, $filename[$i]);
            // echo $temp[$i].'<br/>';      
        }
        $image->preview = implode(',', $temp);
        $image->save();
        return back()->with('success', 'Preview Upload successfully');
MichalOravec's avatar

@fikri1510 If you have set $fillable on your model Multi you can use create

public function store(Request $request)
{
    $request->validate([
        'preview.*' => 'required|image|mimes:jpeg,png,jpg,gif,svg|max:2048'
    ]);
    
    $previews = [];

    foreach ($request->file('preview') as $file) {
        $previews[] = $file->move('uploads/', $file->getClientOriginalName());   
    }

    Multi::create([
        'preview' => implode(',', $previews)
    ]);

    return back()->with('success', 'Preview Upload successfully');
}

But I really don't know why for each preview you don't want to have separately row in your database. And not save path of multi images in same column.

fikri1510's avatar

Yes, I intentionally to have all uploaded filepath in one column since I want if one user upload his product with 10 preview images. I don't know this approach is good. Or need to separate into two tables between user and image table and make relation one to many?

MichalOravec's avatar

This approach is not good. How you mentioned before, use one to many relationship, it will be definitely better.

Please or to participate in this conversation.