Reputation: 182
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
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