Using the Fluent File Rule in Laravel
Published 02/08/2022 | 3927 viewsDid 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!
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 mimetypesFile::types(['text/plain', 'text/csv']); // Using file extensionsFile::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.phppublic function boot(){ File::macro('document', fn() => File::types(['pdf', 'rtf', 'doc', 'docx'])) } // UploadController.phppublic 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!