Kevin Miranda
Kevin Miranda

Reputation: 182

Storing multiple images with multidimensional array

I'm attempting to create a question system that allow the users to create a dynamic amount of question with also a dynamic amount of answer (they can choose from simple text based, to image based answer). Having the following collection of image files in the request:

'image_opt' =>array:4 [▼
          0 => array:1 [▼
              0 => "file_q1_1"
              1 => "file_q1_2"
          ]
          1 => array:1 [▼
              0 => "file_q2_1"
              1 => "file_q2_2"
          ]
          2 => array:4 [▼
              0 => "file_q3_1"
              1 => "file_q3_2"
              2 => "file_q3_3"
              3 => "file_q3_4"
          ]
      ]

How could I fetch each file and store it in the server? So far I've tried this

$answer = new Answer();

$file = $request->image_opt[$i][$j];
$name = str_random(45) . $file->getClientOriginalExtension();

$folder = '/uploads/answers/';

$path = $file->storeAs($folder, $name, 'public');
$answer->answer = $folder . $name;
$answer->question_id = $question->id;
$answer->max_weight = 0;
$answer->weight = $request->image_weight[$i][$j];
$answer->answer_type_id = $question->question_type_id;
$answer->save();

Problem is...I can't fetch the file, I only have the string at that point according to the error.

Call to a member function storeAs() on string

Also tried which didn't work either.

$file = $request->file(image_opt[$i][$j]);

How can I get each file from the collection? $i would represent the current question being stored and $j the answer that's being storede and img_opt is the collection of files.

EDIT:

HTML form:

<div id="image_0" style="display:none;">
    <div id="clone_image_container_0" >
        <div id="clone_image_me_0" >
            <div class="form-group">
                <label class="control-label col-md-3 col-sm-3 col-xs-12" >Respuesta</label>
                <div class="col-md-6 col-sm-6 col-xs-12">
                    <input type="file" class="form-control clonable-increment-name"  name="image_opt[0][]" >
                </div>
            </div>                
            <div class="form-group">
                <label class="control-label col-md-3 col-sm-3 col-xs-12 layer-2-html" >Peso</label>
                <div class="col-md-2 col-sm-2 col-xs-12">
                    <input type="number" class="form-control clonable-increment-name" name="image_weight[0][]" >
                </div>
            </div>
        </div>
    </div>
    <div class="form-group">
        <label class="control-label col-md-3 col-sm-3 col-xs-12" ></label>
        <div class="col-md-2 col-sm-2 col-xs-12">
            <button class="btn btn-success btn-xs clonable-increment-onClick" onClick="CloneFrm(0,'image');" type="button"><i class="fa fa-plus"></i></button>
        </div>
    </div>
</div>

There's a cloner that clone a "question form" and another that clone an "option form". Whenever a question form gets cloned, the name from the input file increase by one like 'img_opt[1][]'

In the case of an image, if there's 2 questions with 2 images each and log the request I would get

img_opt[0][0] = file_q1_1
img_opt[0][1] = file_q1_2
img_opt[1][0] = file_q2_1
img_opt[1][1] = file_q2_2

Upvotes: 1

Views: 502

Answers (1)

Tim Lewis
Tim Lewis

Reputation: 29258

Make sure your <form> element has the enctype="multipart/form-data" attribute to properly handle image uploads in Laravel. Omitting this can cause issues, and obviously is in this situation.

<form method="POST" action="..." enctype="multipart/form-data">

This error:

Call to a member function storeAs() on string

Is due to how $request->image_opt[$i][$j] is defaulting to a string value for uploaded images. This would be equivalent to calling $request->input("image_opt")[$i][$j], but this isn't an input() variable, it's a file() variable.

Next error:

Invalid argument supplied for foreach()

For the same reason, foreach($request->file("image_opt) AS $images){ ... } is returning null when enctype is omitted. It should be an array, and would be if you used $request->input(), but that's also an error.

TL:DR; don't forget enctype; omitting it was the cause of the various issues encountered.

Upvotes: 1

Related Questions