Using the Fluent File Rule in Laravel

Published 02/08/2022

Did you know there's a cool new File validation rule in Laravel? Let's check it out, and discover some advanced usage you won't find in the docs!

An example of the new fluent File rule in Laravel.

I recently added a fluent class for specifying file rules in Laravel. You can see the PR in full here. The official documentation will get you up and running, but it's missing perhaps the single most powerful aspect of this new framework feature. Let's dive in!

The basics

At its most basic, the new File rule gives you the ability to use a fluent chain when definining validation for uploads instead of rules specified as strings. This obviously looks cleaner and has the benefit of full IDE autocompletion.

Previously, your file validation might have looked something like this:

public function store($request)
{
$request->validate([
'file' => ['file', 'mimes:pdf,doc,docx,rtf', 'min:512', 'max:12228']
]);
}

Using the new File rule, you can use the following syntax instead:

use Illuminate\Validation\Rules\File;
 
public function store($request)
{
$request->validate([
'file' => [File::types(['pdf', 'doc', 'docx', 'rtf'])->min(512)->max(12 * 1024)]
]);
}

Pretty snazzy hey?

mimetypes vs. mimes

Do you know the difference between the mimetypes and mimes validation rules? No? Well, you pass mimetypes full mimetypes, such as text/plain, image/png and text/csv. On the other hand, mimes receives file extensions, such as txt, png and csv.

You should only be using one rule or the other in validation, and it can be annoying remembering which is which. So, File::types accepts either! If you pass mimetypes, the File rule will output mimetypes validation errors. Use file extensions, and the rule will output mimes validation errors.

// Using mimetypes
File::types(['text/plain', 'text/csv']);
 
// Using file extensions
File::types(['txt', 'csv']);

Custom filetypes

If you take a look at the official documentation on this feature, you'll see that there is a built in File::image method that you can use for uploads that should be limited to image types.

// This...
File::image();
 
// is the same as this...
File::types(['jpg', 'jpeg', 'png', 'bmp', 'gif', 'svg', 'webp');

That's cool and all, but what about other types of files? For example, what if you wanted to have a File::document method? Well, that's exactly why the File rule is Macroable!

// AppServiceProvider.php
public function boot()
{
File::macro('document', fn() => File::types(['pdf', 'rtf', 'doc', 'docx']))
}
 
// UploadController.php
public function store($request)
{
$request->validate([
'file' => [File::document()->max(20 * 1024)],
]);
}

I think this is the true power of the File rule. We often have very domain specific file types in our applications, and being able to define them as a File macro is super powerful. We're already making use of custom types in the Worksome codebase.

Wrapping up

So, that's the new File rule in Laravel! I hope you get as much benefit from it as I have. Keep in mind those advanced features that give you maximum power from this feature.

Until next time, happy coding!

Like what you see?

If you enjoy reading my content, please consider sponsoring me. I don't spend it on cups of coffee; it all goes towards freeing up more of my time to work on open source, tutorials and more posts like this one.