1

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
13
  • $request->file(image_opt[$i][$j]); looks incorrect; it would be $request->file("image_opt")[$i][$j];, although I'm not sure where you're getting image_opt; maybe include your form/post data? Commented Sep 3, 2019 at 17:29
  • But doing $request->file("image_opt") how can I specify, for example, that he should get file "file_q3_2"? Commented Sep 3, 2019 at 17:30
  • Maybe that would be $request->file("image_opt.2.1")? Or, you could loop $request->file("image_opt"), like foreach($request->file("image_opt") AS $image){ ... } Commented Sep 3, 2019 at 17:33
  • Just tried $request->file("image_opt.2.1"), it did not work. Wouldn't foreach($request->file("image_opt") AS $image){ ... } fail because file("image_opt") would be trying to read an array of arrays? Commented Sep 3, 2019 at 17:39
  • Hmm, yeah. And no, it wouldn't fail per-say, it just means that $image would be an array, so you'd need to do another foreach (nested looping) Commented Sep 3, 2019 at 17:41

1 Answer 1

1

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.

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you for your time and patience.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.