Search code examples
laravellaravel-validationlaravel-filesystem

How to Validate File Upload in Laravel


I've completed a tutorial to upload image files. How can I validate file uploads in the view when a user uploads a file larger than 2MB?

create.blade.php

@if (count($errors) > 0)
    <div class="alert alert-danger">
        <strong>Whoops!</strong> Errors.<br><br>
        <ul>
            @foreach ($errors->all() as $error)
                <li>{{ $error }}</li>
            @endforeach
        </ul>
    </div>
@endif
@if(session('success'))
    <div class="alert alert-success">
        {{ session('success') }}
    </div>
@endif
<div class="form-group">
    <input type="file" name="photos[]" multiple aria-describedby="fileHelp"/>
    <small id="fileHelp" class="form-text text-muted">jpeg, png, bmp - 2MB.</small>
</div>

Rules

public function rules()
{
    $rules = [
        'header' => 'required|max:255',
        'description' => 'required',
        'date' => 'required',
    ];
    $photos = $this->input('photos');
    foreach (range(0, $photos) as $index) {
        $rules['photos.' . $index] = 'image|mimes:jpeg,bmp,png|max:2000';
    }

    return $rules;
}

Everything is ok, however when I try to upload a file which is larger than 2MB it gives me an error:

Illuminate \ Http \ Exceptions \ PostTooLargeException No message

How can I solve this and secure this exception?


Solution

  • in laravel you can not handle this case in controller as it will not get to controller/customrequest and will be handled in middleware so you can handle this in ValidatePostSize.php file:

    public function handle($request, Closure $next)
     {
      //       if ($request->server('CONTENT_LENGTH') > $this->getPostMaxSize()) 
                {
                 //            throw new PostTooLargeException;
      //        }
    
       return $next($request);
     }
    
    
    
    /**
     * Determine the server 'post_max_size' as bytes.
     *
     * @return int
     */
    protected function getPostMaxSize()
    {
        if (is_numeric($postMaxSize = ini_get('post_max_size'))) {
            return (int) $postMaxSize;
        }
    
        $metric = strtoupper(substr($postMaxSize, -1));
    
        switch ($metric) {
            case 'K':
                return (int) $postMaxSize * 1024;
            case 'M':
                return (int) $postMaxSize * 1048576;
            default:
                return (int) $postMaxSize;
        }
    }
    

    with your custom message

    Or in App\Exceptions\Handler:

       public function render($request, Exception $exception)
       {
          if ($exception instanceof \Illuminate\Http\Exceptions\PostTooLargeException) {
            // handle response accordingly
          }
          return parent::render($request, $exception);
       }
    

    Else need to update php.ini

    upload_max_filesize = 10MB
    

    If you dont to work with any of above solutions you can use client side validation like if you are using jQuery e.g.:

    $(document).on("change", "#elementId", function(e) {
     if(this.files[0].size > 7244183)  //set required file size 2048 ( 2MB )
      { 
         alert("The file size is too larage");
        $('#elemendId').value = ""; 
      }
    });
    

    or

    <script type="text/javascript"> 
     function ValidateSize(file) { 
       var FileSize = file.files[0].size / 1024 / 1024; // in MB 
       if (FileSize > 2) { 
         alert('File size exceeds 2 MB'); 
          $(file).val(''); //for clearing with Jquery 
       } else { 
    
       } 
     } 
    </script>