framework: [5.1] [5.2] Required file rules dont work when file size greater than max_file_upload size

This issue has come up before: https://github.com/laravel/framework/issues/4467 & https://github.com/laravel/framework/issues/4226

@GrahamCampbell said in #4467 that there is an existing pull that deals with this - but it is not fixed - it is still broken - and I cant find any PR that seems to deal with this?

The problem is simple:

  1. Upload file greater than max_file_upload (but less than post_max_size)
  2. PHP will send the request to Laravel, but has cleared the file because it is larger than max_file_upload
  3. Laravel does a required check - sees the file is not there, and reports “The file is required”.

Obvious this is very confusing to users - because they did attach a file - but the website is telling them they didnt.

The general solution would be to add a simple check to see if there is an error on the $_FILES global - which would indicate there was a file attached. But then you run into a new problem - if the file is required, but it is not actually there - then you cant let required pass - it must fail.

So I think the solution is to return a custom message for file validations - with some checks as to why the required failed?

I’m happy to do the PR myself - but I’m looking for some guidance/direction on how we can solve this problem…

About this issue

  • Original URL
  • State: closed
  • Created 9 years ago
  • Comments: 26 (12 by maintainers)

Most upvoted comments

I’ve done a picture to try to illustrate the problem

fileuplad

Although I may not hold much weight as I am new here, I would agree with @Arrilot that it would be better to modify the existing “required” rule than to force users to add a new “file” rule to any file upload validations.

A bugfix should not require end users to take an action, it should be invisible to them. Although adding a “file” validation rule is something that can be discussed as a new feature, it’s separate from the bug immediately at hand.

{!! Form::open(array('route' => 'resizeImagePost', 'files' => true)) !!}

I’ve been digging around the validation rules - and I have an idea how we might solve this, plus improve the validation rules at the same time.

The validation rule required for files is actually a bit strange:

elseif ($value instanceof File)
{
    return (string) $value->getPath() != '';
}

The only way a $value can be an instanceOf File is if the user originally sent a file. So by definition - this means the required rule has been meet, and should always pass.

The problem is that if the file upload had an error, then the ->getPath() returns blank, and the required rule is now false - giving an incorrect error “File is required” - when it should be more like “There was an error uploading”.

I propose we remove that elseif statement from the required rules.

And we add a file validation rule. We have string and array validation rules. We also have an image rule. But we dont have a general file validation rule? If you want to allow any file, it is difficult without setting mimes - but what if you want to allow any mime?

The file rule could be something like this (needs refactoring - but you get the idea):

protected function validateFile($attribute, $value, $parameters)
{
     if ( ! $this->isAValidFileInstance($value)) {
             return false;
     }

     $minFileSize = isset($parameters[0]) ? $parameters[0] : 1;

     if ($this->getSize($attribute, $value) < $minFileSize) {
             return false;
     }

     $maxFileSize = isset($parameters[1]) ? $parameters[1] : ini_get('max_file_upload');

     if ($this->getSize($attribute, $value) > $maxFileSize) {
              return false;
     }

     return true;
}

Then in your validation rules you just have to do

'file' => 'required|file:1,10000'

or you can do

'file' => 'required|file'

Which defaults to min size of 1 (because you shouldnt accept filesizes of 0 bytes), and max file size of whatever your PHP max_file_upload config is (which is your limit no matter what).

and you can easily combine it with image and mime rules

'file' => 'required|file:1,10000|mime:pdf,doc,txt'
'image' => 'required|file:1,10000|image'

or like this:

'file' => 'required|file|mime:pdf,doc,txt'
'image' => 'required|file|image'

@GrahamCampbell - no - separate issue.

#8202 is when post > post_max_size

This is when file > max_file_upload - which is much more common