Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

Dracip's avatar
Level 24

file upload validation works unexpected

Hi,

I've an issue with an file/picture upload.

I'm using a request-validator (called "FileRequest") with following rule/s:

$rules['file'] = 'image|max:500';

These are only test values. If I now upload a file that ist breaking the php "upload_max_filesize" the validation does'nt work anymore (i can use other files than images and can also be bigger than 500KB). Is this correct/expected behavior? If I additionally check the file in my controller like this:

$inputFile = $request->file('file');
if (!$inputFile->isValid()) {
    dd($inputFile->getErrorMessage());
}

The validator tells the expected "The file "xxxxxx.yyy" exceeds your upload_max_filesize ini directive (limit is 2048 KiB)."

If if try these rule/s:

$rules['file'] = 'required|image|max:500';

The validator is missing the upload and tells "The file field is required.", also missing a correct exceeds message.

Can anyone help me?

0 likes
10 replies
moharrum's avatar

I'm actually working on a user avatar upload section right now, this might be interesting.

What do you mean by request-validator, are you using FormRequests or the Validator Facade? I'm using a form request and here are my rules:

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            'avatar' => 'required|image|max:10240|mimes:jpeg,jpg,gif,bmp,png' // file size 10MB
        ];
    }

You might also consider using the Intervention package http://image.intervention.io/ to make your life easier.

Snapey's avatar

bear in mind that if you exceed the php limit then the server will refuse the upload before it reaches your validator.

2 likes
Dracip's avatar
Level 24

I've following settings in my php:

post_max_size: 8M
upload_max_filesize: 2M

Testfile: ~4M

Request:

<?php namespace App\Http\Requests;

class FileRequest extends Request {
    public function authorize(){
        return true;
    }

    public function rules(){
        return [
            'file' => 'required|image|max:300'
        ];
    }
}

Simplified Controller function:

public function storeUpload(FileRequest $request, $id){
        $inputFile = $request->file('file');

        if ($inputFile->isValid()) {
            dd('All is fine');
        } else {
            dd('Error: '.$inputFile->getErrorMessage());
        }
    }

In this case I'll be redirected and the message for the file-Field is: "The file field is required."

If I remove the required validator in the request:

<?php namespace App\Http\Requests;

class FileRequest extends Request {
    public function authorize(){
        return true;
    }

    public function rules(){
        return [
            'file' => 'image|max:300'
        ];
    }
}

I see the following message, from else section in my controller: "Error: The file "testfile-for.upload" exceeds your upload_max_filesize ini directive (limit is 2048 KiB)."

If I try the same with a 500KB file I see the expected message for the form field validation: "The file may not be greater than 300 kilobytes."

skliche's avatar

@mgrulich Like @Snapey already mentioned, if the file is larger then permitted by your PHP configuration then it does not reach your application and therefor your validator won't fail on the file size. The error message "Error: The file %s exceeds your upload_max_filesize ini directive" is from PHP and just signals what went wrong.

Dracip's avatar
Level 24

Hi @skliche , yes but the request validator is working before my controller starts to work, right? Why is the request validator passing without errors in case of a not required field and the additional check in my controller is invalid?

How can I fix this case, if it should not be an error?

skliche's avatar

@mgrulich I see and you are right, both the image and max validator rules should fail when the file upload has failed.

Did you try debugging or adding logging-statements to the validator class to see what's going on? What version of Laravel are you using?

Dracip's avatar
Level 24

Hi @skliche I'm using Laravel 5.2.12

I haven't debugged the validator yet.

Dracip's avatar
Level 24

I can see the error in the UploadedFile object before the rules are set. But I can not find a check of this error within the required or image validator.

If I debugging the file instance pre-rules return within form-request:

<?php namespace App\Http\Requests;

class FileRequest extends Request {
    public function authorize(){
        return true;
    }

    public function rules(){
        dd($this->file);
        return [
            'file' => 'required|image|max:300'
        ];
    }
}

I can see the following (with attribute error set to 1):

UploadedFile {#30 ▼
  -test: false
  -originalName: "testfile.png"
  -mimeType: "application/octet-stream"
  -size: 0
  -error: 1
  path: ""
  filename: ""
  basename: ""
  pathname: ""
  extension: ""
  realPath: "</real/path/to/laravel/instance>"
  aTime: 1970-01-01 01:00:00
  mTime: 1970-01-01 01:00:00
  cTime: 1970-01-01 01:00:00
  inode: false
  size: false
  perms: 00
  owner: false
  group: false
  type: false
  writable: false
  readable: false
  executable: false
  file: false
  dir: false
  link: false
}

The required check for a file looks only following:

/**
     * Validate that a required attribute exists.
     *
     * @param  string  $attribute
     * @param  mixed   $value
     * @return bool
     */
    protected function validateRequired($attribute, $value)
    {
        if (is_null($value)) {
            return false;
        } elseif (is_string($value) && trim($value) === '') {
            return false;
        } elseif ((is_array($value) || $value instanceof Countable) && count($value) < 1) {
            return false;
        } elseif ($value instanceof File) {
            return (string) $value->getPath() != '';
        }

        return true;
    }

The latest elseif returns "false", so I think the general upload issue should be checked before, or is there maybe an other validator which I can add to check of this error?

@JeffreyWay have you an idea?

skliche's avatar
skliche
Best Answer
Level 42

@mgrulich I could reproduce your problem and had a look at the Validator class:

  • The method isValidatable() returns false on a failed upload (instance of UploadedFile with error == 1).
  • If you look at the method isValidatable() you will see that it performs three checks and the culprit is presentOrRuleIsImplicit().
  • presentOrRuleIsImplicit() performs two checks, validateRequired() and isImplicit(), both return false.
  • The problem is within validateRequired(): In case of an instance of File it checks whether the object contains a path. Since it does not contain a path this method returns false.
  • This is the reason why isValidatable() returns false which in turn results in the validation rules not being evaluated / the actual validation not being performed.

This looks intentional even though I would consider it a bug. If a file object is present and it does not contain a path but there are rules defined for it then the validation should fail.

1 like

Please or to participate in this conversation.