Search code examples
phplaravelvalidationfile-uploadfilesize

Laravel Validate Array of Files Total Allowable Upload Size


My View has an array of file inputs like

<input type="file" name="videos[]" />
<input type="file" name="videos[]" />
...
...

and I want to validate for the total allowable upload size (Eg: Total Allowable Upload limit is 3Mb). I've written the validation like

$validatedData = $request->validate([
     'videos.*' => 'present|file|mimetypes:video/mp4,video/ogg|max:3000',
]);

but this validates for 3Mb per video.

I've tried

$validatedData = $request->validate([
    'videos' => 'file|max:3000',
    'videos.*' => 'present|file|mimetypes:video/mp4,video/ogg|max:3000',
]);

/*------------------------------------------------*/

$validatedData = $request->validate([
    'videos' => 'array|max:3000',
    'videos.*' => 'present|file|mimetypes:video/mp4,video/ogg|max:3000',
]);

but the validation is not working for total upload size greater than 3Mb. Do I have to write a Custom Validation Rule to validate the total uploaded file size limit. Or is there any predefined validation rule? Any help appreciated.

Thank You!


Solution

  • I think the best way to validate the total size is by adding a custom validation rule, here is how to do that:

    In your controller:

    $validatedData = $request->validate([
        'videos' => 'array|max_uploaded_file_size:3000',
        'videos.*' => 'present|file|mimetypes:video/mp4,video/ogg',
    ]);
    

    Register custom validation in AppServiceProvider.php

    public function boot() {
    
        Validator::extend('max_uploaded_file_size', function ($attribute, $value, $parameters, $validator) {
            
            $total_size = array_reduce($value, function ( $sum, $item ) { 
                // each item is UploadedFile Object
                $sum += filesize($item->path()); 
                return $sum;
            });
    
            // $parameters[0] in kilobytes
            return $total_size < $parameters[0] * 1024; 
    
        });
    
    }