How to validate various files in Laravel?

Laravel has a powerful set of validation rules, but sometimes you need to validate the specific types of files and not all scenarios are explained in Laravel documentation. In this article, I will observe the ways to validate different files such as images, base64, audio and video, CSV, Excel files, and others. Please choose which type of file you need to validate in the table of contents below.

Table of Contents

Main file validators

To validate successfully uploaded file You can use file validator:

'file_input' => 'file',

To make file input required You can use the required validator same as with any other input types:

'file_input' => 'file|required',

MIME type validators

To validate the MIME type of uploaded file use the mimetypes validator:

'file_input' => 'file|mimetypes:text/plain,text/html',

To validate the MIME type of uploaded file by file extension use mimes validator:

'file_input' => 'file|mimes:jpg,png',

File size validators

If You want to validate the file against the exact file size in KB then use the size validator:

'file_input' => 'file|size:1024',

Use max validator to check if the file size is not greater than the given value:

'file_input' => 'file|max:1024',

Use min validator to check if the file size is not less than the given value:

'file_input' => 'file|min:1024',

Or You can use between validator to check if the file size is between given min and max values:

'file_input' => 'file|between:1024,2048',

How to validate multiple files in Laravel?

Validate multiple files in Laravel?

If you need to validate an array of files in Laravel then your input should have the multiple attribute and the input name should be an array, like in the example below:

<input type="file" id="file" name="user_files[]" multiple>

And then add dot following with asterisk symbol near input name in your validation rules:

'user_files.*' => 'file|between:1024,2048',

If for some reason you need to validate each uploaded file from array differently then you can specify a specific index of file:

'user_files.1' => 'file|between:1024,2048',
'user_files.2' => 'file|between:2048,4096',

Note that if you want to make multiple files input to be required then you should not use dot/asterisk or dot/index:

'user_files' => 'required',
'user_files.*' => 'file|between:1024,2048',

How to validate images in Laravel?

Validate images in Laravel

To check if the uploaded file is an image with then use the image validator. This validator checks if the file has one of these extensions: jpg, jpeg, png, bmp, gif, svg, or webp.

'file_input' => 'image',

If you need to validate an image against custom MIME types then use MIME type validators. If you need to validate the image file size then use file size validators. These validators are explained above. An example of validating an image against custom MIME types and file size could be:

'file_input' => 'file|mimes:jpg,png|max:512',

How to validate image dimensions?

To validate image dimensions Laravel has the dimensions validator which can be used with 7 constraints:

  • min_width
  • max_width
  • min_height
  • max_height
  • width
  • height
  • ratio

Example of validating image dimensions:

'image' => 'dimensions:max_width=1000,max_height=500,ratio=2/1',

How to validate base64 files in Laravel?

Validate base64 files in Laravel

Sometimes you need to validate base64 files. For example, in the frontend, you have an image creation tool that sends created images in base64 format to the backend. Of course, you should validate this base64 encoded image for security reasons, and also maybe you need to validate base64 image dimensions or so. In this case, I would recommend the crazybooot/base64-validation package for Laravel.

It is easy to install with composer:

composer require crazybooot/base64-validation

The package has these validators:

  • base64max
  • base64min
  • base64dimensions
  • base64file
  • base64image
  • base64mimetypes
  • base64mimes
  • base64between
  • base64size

These validators are equivalent to the native Laravel file validators I wrote about above. There is an example of how to use them:

'created_image' => 'base64image|base64size:1024|base64dimensions:min_width=100,min_height=200',

This package uses error messages from its equivalent from the native Laravel file validator. For example, the base64image validator will show an error message of the native Laravel image validator. If you want to use your own error messages you need to publish package configuration file with this command:

php artisan vendor:publish --provider="Crazybooot\Base64Validation\Providers\ServiceProvider" --tag=config

This command will add config/base64validation.php file. Open it and change replace_validation_message to false:

'replace_validation_messages' => false,

And then just add validation error messages as you simply add them. For example, open the resources/lang/en/validation.php file and add these lines:

'base64max' => 'Your custom error message for base64 validator',
'base64min' => 'Your custom error message for base64 validator',
'base64dimensions' => 'Your custom error message for base64 validator',
'base64file' => 'Your custom error message for base64 validator',
'base64image' => 'Your custom error message for base64 validator',
'base64mimetypes' => 'Your custom error message for base64 validator',
'base64mimes' => 'Your custom error message for base64 validator',
'base64between' => 'Your custom error message for base64 validator',
'base64size' => 'Your custom error message for base64 validator',

How to validate audio and video files in Laravel?

Validate audio and video files in Laravel

To check if the uploaded file is an audio or video file then use MIME type validators. Below is a list of audio mime types and a list of video mime types. However, Laravel’s video/audio files MIME types guessing is not reliable. That’s because I created a package that adds audio and video validators to your Laravel project which is called minuteoflaravel/laravel-audio-video-validator. To install this package you should install ffmpeg multimedia framework:

  • On Debian/Ubuntu, run sudo apt install ffmpeg
  • On macOS with Homebrew: brew install ffmpeg

After that install the package via composer:

composer require minuteoflaravel/laravel-audio-video-validator

The package adds these validators:

  • audio
  • video
  • codec
  • duration
  • duration_max
  • duration_min
  • video_width
  • video_height
  • video_max_width
  • video_max_height
  • video_min_width
  • video_min_height

Here are examples of how to use those validators:

$request->validate([
    'audio' => 'required|audio|duration_min:30|duration_max:300|codec:mp3,pcm_s16le',
]);
$request->validate([
    'video' => 'required|video|duration:60|codec:h264|video_width_max:1920|video_height_max:1080',
]);

The first one check if uploaded file is an audio file, if its duration is between 30 and 300 seconds and if an audio file codec name is mp3 or pcm_s16le(.wav). The second one checks if uploaded file is a video file, if its duration is exactly 60 seconds, if its codec name is h264(.mp4) and if its resolution is not greater than 1900×1080.

Audio MIME types list

.aifaudio/aiff
.aifaudio/x-aiff
.aifcaudio/aiff
.aifcaudio/x-aiff
.aiffaudio/aiff
.aiffaudio/x-aiff
.auaudio/basic
.auaudio/x-au
.funkaudio/make
.gsdaudio/x-gsm
.gsmaudio/x-gsm
.itaudio/it
.jamaudio/x-jam
.karaudio/midi
.laaudio/nspaudio
.laaudio/x-nspaudio
.lamaudio/x-liveaudio
.lmaaudio/nspaudio
.lmaaudio/x-nspaudio
.m2aaudio/mpeg
.m3uaudio/x-mpequrl
.midaudio/midi
.midaudio/x-mid
.midaudio/x-midi
.midiaudio/midi
.midiaudio/x-mid
.midiaudio/x-midi
.mjfaudio/x-vnd.audioexplosion.mjuicemediafile
.modaudio/mod
.modaudio/x-mod
.mp2audio/mpeg
.mp2audio/x-mpeg
.mp3audio/mpeg3
.mp3audio/x-mpeg-3
.mpaaudio/mpeg
.mpgaudio/mpeg
.mpgaaudio/mpeg
.myaudio/make
.pfunkaudio/make
.pfunkaudio/make.my.funk
.qcpaudio/vnd.qcelp
.raaudio/x-pn-realaudio
.raaudio/x-pn-realaudio-plugin
.raaudio/x-realaudio
.ramaudio/x-pn-realaudio
.rmaudio/x-pn-realaudio
.rmiaudio/mid
.rmmaudio/x-pn-realaudio
.rmpaudio/x-pn-realaudio
.rmpaudio/x-pn-realaudio-plugin
.rpmaudio/x-pn-realaudio-plugin
.s3maudio/s3m
.sidaudio/x-psid
.sndaudio/basic
.sndaudio/x-adpcm
.tsiaudio/tsp-audio
.tspaudio/tsplayer
.vocaudio/voc
.vocaudio/x-voc
.voxaudio/voxware
.vqeaudio/x-twinvq-plugin
.vqfaudio/x-twinvq
.vqlaudio/x-twinvq-plugin
.wavaudio/wav
.wavaudio/x-wav
.xmaudio/xm

Video MIME types list

.aflvideo/animaflex
.asfvideo/x-ms-asf
.asxvideo/x-ms-asf
.asxvideo/x-ms-asf-plugin
.avivideo/avi
.avivideo/msvideo
.avivideo/x-msvideo
.avsvideo/avs-video
.difvideo/x-dv
.dlvideo/dl
.dlvideo/x-dl
.dvvideo/x-dv
.flivideo/fli
.flivideo/x-fli
.fmfvideo/x-atomic3d-feature
.glvideo/gl
.glvideo/x-gl
.isuvideo/x-isvideo
.m1vvideo/mpeg
.m2vvideo/mpeg
.mjpgvideo/x-motion-jpeg
.moovvideo/quicktime
.movvideo/quicktime
.movievideo/x-sgi-movie
.mp2video/mpeg
.mp2video/x-mpeg
.mp2video/x-mpeq2a
.mp3video/mpeg
.mp3video/x-mpeg
.mpavideo/mpeg
.mpevideo/mpeg
.mpegvideo/mpeg
.mpgvideo/mpeg
.mvvideo/x-sgi-movie
.qtvideo/quicktime
.qtcvideo/x-qtc
.rvvideo/vnd.rn-realvideo
.scmvideo/x-scm
.vdovideo/vdo
.vivvideo/vivo
.vivvideo/vnd.vivo
.vivovideo/vivo
.vivovideo/vnd.vivo
.vosvideo/vosaic
.xdrvideo/x-amt-demorun
.xsrvideo/x-amt-showrun

How to validate CSV files in Laravel?

Validate CSV files in Laravel

When we are talking about CSV files validation then we mean one of three different validation variants:

  1. Check if MIME type or file extention matches your needs
  2. Check if uploaded file is formatted in CSV format
  3. Check if uploaded file CSV file structure matches yout needs

The first variant should be used when you want to check if the uploaded file is a CSV file. To do this use the MIME type or extension validators but always remember that the user can rename any file extension to *.csv and also if you validate against MIME type then keep in mind that a real CSV file can have the text/plain MIME type. So in my opinion, if you need to be sure that the uploaded file is a CSV file then you should use the second validation variant where you check if the uploaded file is formatted in CSV format. You should use a third validation variant when you want to validate cells of the uploaded CSV file. Below I will review the second and third variants.

To check if the uploaded file is formatted in CSV format then you can use the simple package that I created for this purpose which is called minuteoflaravel/laravel-csv-validator. CSV validator, which is added by this package, parses the uploaded file using parsecsv/php-parsecsv library and if there are no errors during file parsing then validation is passed. Install this package with composer:

composer require minuteoflaravel/laravel-csv-validator

And then add csv validator to your validation rules:

 'uploaded_file' => 'csv',

You can customize the error message. Open resources/lang/en/validation.php file and add your message:

 'csv' => 'The :attribute must be a CSV file.',

If you choose to validate with a third validation variant – CSV file cells validation – then I suggest using SUKOHI/CsvValidator package. This package allows you to select default Laravel validation rules for each cell. To install this package run the composer command:

composer require sukohi/csv-validator:3.*

Then add validation rules for columns to array:

$csv_rules = [
    0 => 'required',
    1 => 'integer',
    2 => 'required|min:10'
];

Create options array:

$options = [
    'encoding' => 'sjsin-win',
    'start_row' => 1,   // <- Starting validation from row one, not zero.
    'end_row' => 4,     // <- Ending validation
    'row_callback' => function($row_number, $row_data) {

        return true;    // `false` means skipping validation

    }
];

And then add a validator to your validation rules:

$request->validate([
    'csv_file' => [
        new Csv($csv_rules, $options)
    ]
]);

If you need to add validation rules for cells by column name then I suggest using another package which is called Konafets/laravel-csv-validator. This package is similar to the previous one but by using it you can add a validation rule to columns by column name from header row. To install:

composer require konafets/laravel-csv-validator:1.0-dev

And there is a code example of how to use this package:

$csvPath = 'employees.csv';
$rules = [
    'First Name' => 'required|string',
    'Last Name' => 'required|string',
    'Year of Birth' => 'required|numeric',
];

$csvValidator = CsvValidator::make($csvPath, $rules);

if($csvValidator->fails()) {
    $errors = $csvValidator->getErrors();
} else {
    $csvData = $csvValidator->getData();
}

How to validate Excel files in Laravel?

Validate Excel files in Laravel

To validate Excel files you can use MIME type validators. Here is an example of how to validate against few MIME types:

'file_input' => 'file|mimetypes:application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/excel',

In the example added only two MIME types. Below is full list of Excel MIME types.

Excel MIME types list

.xlsxapplication/vnd.openxmlformats-officedocument.spreadsheetml.sheet
.xlsmapplication/vnd.ms-excel.sheet.macroEnabled.12
xlsbapplication/vnd.ms-excel.sheet.binary.macroEnabled.12
.xlapplication/excel
.xlaapplication/excel
.xlaapplication/x-excel
.xlbapplication/excel
.xlbapplication/vnd.ms-excel
.xlbapplication/x-excel
.xlcapplication/excel
.xlcapplication/vnd.ms-excel
.xlcapplication/x-excel
.xldapplication/excel
.xldapplication/x-excel
.xlkapplication/excel
.xlkapplication/x-excel
.xllapplication/excel
.xllapplication/vnd.ms-excel
.xllapplication/x-excel
.xlmapplication/excel
.xlmapplication/vnd.ms-excel
.xlmapplication/x-excel
.xlsapplication/excel
.xlsapplication/vnd.ms-excel
.xlsapplication/x-msexcel
.xlsapplication/x-excel
.xltapplication/excel
.xltapplication/x-excel
.xlvapplication/excel
.xlvapplication/x-excel
.xlwapplication/excel
.xlwapplication/vnd.ms-excel
.xlwapplication/x-excel

How to validate XML files in Laravel?

Validate XML files in Laravel

To validate XML files you can use MIME type validators. Here is an example:

'file_input' => 'file|mimetypes:application/xml,text/xml',