For a laravel project im trying to upload multiple files. The files are optional so I want to do a check before I loop through all the images.
My form input part.
{!! Form::open(array( 'files'=>true)) !!}
{!! Form::file('images[]', array('multiple'=>true, 'class' => 'form-control')) !!}
{!! Form::close() !!}
(the form has enctype="multipart/form-data" and the input field has multiple="1")
My current code for checking:
$files = Input::file('images');
$uploaded = 0;
$failed = 0;
if(!empty($files)){
try {
foreach ($files as $file) {
//upload file $uploaded ++ or $failed ++;
$rules = array('file' => 'required|image'); // 'required|mimes:png,gif,jpeg,txt,pdf,doc'
$validator = Validator::make(array('file' => $file), $rules);
if ($validator->passes()) {
//if file uploaded succesfuly $uploaded++;
}
else{
$failed++;
}
}
}
catch(Exception e){
//Handle error
}
}
When i change !empty($files) with if(count($files) > 0) it still goes in the foreach.
I use $failed and $uploaded, after this part of code is finished, to show a message depending on the ammount of failed/uploaded. However when I dont select any file $failed is 1 (even if array is empty). Looping the $files to count the ammount, before I loop them to upload feels like a waste of memory/time/etc, is there a better way than looping the $files array to get the ammount of files?
Subquestion: Why is it running the foreach loop when it's empty?
I'm assuming your stripped down form looks something like this:
<form method="POST" action="target/url" accept-charset="UTF-8" enctype="multipart/form-data">
<input name="images[]" type="file">
<input name="images[]" type="file">
<input type="submit" value="Click Me">
</form>
In this case, your $images
variable is always going to be an array. The results of the file uploads are the entries inside your array. If you were to submit the above form and run the following code:
$files = Input::file('images');
dd($files);
You would get:
array:2 [
0 => null
1 => null
]
As you can see, your $images
array isn't empty. It has two entries in it, one for each file upload.
So, you have a couple options. You can move your empty check:
$files = Input::file('images');
foreach ($files as $file) {
// check to see if the file upload is empty
if (!empty($file)) {
$rules = array('file' => 'required|image'); // 'required|mimes:png,gif,jpeg,txt,pdf,doc'
$validator = Validator::make(array('file' => $file), $rules);
if ($validator->passes()) {
// success
} else {
// fail
}
}
}
Or, you can filter out all the empty results beforehand, using array_filter()
:
// filter out all loosely-false entries (null == false)
$files = array_filter(Input::file('images'));
foreach ($files as $file) {
$rules = array('file' => 'required|image'); // 'required|mimes:png,gif,jpeg,txt,pdf,doc'
$validator = Validator::make(array('file' => $file), $rules);
if ($validator->passes()) {
// success
} else {
// fail
}
}