Currently Available: Need a skilled Software Developer for your next project?
Categories
Laravel

Validating File Uploads in Laravel

When a Laravel request includes an uploaded file, the code should validate it before storing it. Laravel provides rules for checking file type, size, and image dimensions, as well as rules for requiring an upload or allowing it to be omitted. After validation succeeds, the code can call store on the uploaded-file object to save the file to a configured storage disk.

A MIME type is a label that describes a file’s format, such as image/png. Laravel guesses this type from the file’s contents. That check helps distinguish file content from a filename extension, such as .png, which the user or browser assigns.

Check file type, size, and image dimensions

Laravel’s mimes and mimetypes rules check the MIME type Laravel detects from the file’s contents. Despite its name, mimes:png does not require the filename to end in .png: valid PNG content named photo.txt can pass. The separate extensions rule checks the assigned filename extension. Combine it with a content-based rule when both must match. Laravel describes these options in its file validation documentation.

For example, this rule set accepts an image, limits its size, and constrains its dimensions:

use Illuminate\Http\Request;
use Illuminate\Validation\Rule;
use Illuminate\Validation\Rules\File;

public function store(Request $request)
{
    $validated = $request->validate([
        'photo' => [
            'required',
            File::image()
                ->max('5mb')
                ->dimensions(
                    Rule::dimensions()
                        ->maxWidth(2000)
                        ->maxHeight(2000)
                ),
        ],
    ]);

    $path = $validated['photo']->store('photos', 'public');

    // Save $path with the related record.
}

File::image() checks that the upload uses an image format Laravel accepts. Laravel’s documented formats include JPG, JPEG, PNG, BMP, GIF, WebP, AVIF, HEIC, and HEIF. The rule excludes SVG by default because of cross-site scripting (XSS) concerns. Passing the rule does not prove that the file is safe to process.

The max('5mb') constraint sets the largest file size Laravel accepts during validation. The fluent file rule also supports the kb, gb, and tb suffixes. Laravel’s dimensions rule can limit minimum or maximum width and height, require exact dimensions, or constrain the aspect ratio, which compares an image’s width with its height. Choose limits that match the files your feature needs; the example values are not universal requirements.

Require an upload or allow it to be omitted

Use required when the request must include a nonempty upload. Laravel treats an uploaded file with no path as empty, and the file rule checks that the value is a successfully uploaded file. The fluent File::image() rule in the example performs file and image validation.

For an optional upload, remove required and add nullable. Laravel’s default middleware maps empty strings to null, so nullable allows that value through validation. It does not require the field to be present. Store the file only when the validated data contains one:

$validated = $request->validate([
    'photo' => [
        'nullable',
        File::image()->max('5mb'),
    ],
]);

if (isset($validated['photo'])) {
    $path = $validated['photo']->store('photos', 'public');
}

The isset check returns false when the file is omitted or null. Without that guard, the code could try to call store when there is no uploaded file.

Store only the validated upload

After validation succeeds, Laravel makes the upload available as an Illuminate\Http\UploadedFile object. Laravel saves the file to a configured disk when the code calls store on that object, then returns its stored path. In the first example, photos is the directory, and public is the disk name. Laravel generates a unique filename and derives its extension from the file’s MIME type; the request documentation describes uploaded-file handling.

Save the returned path with the related database record so the code can retrieve the file later. Choose the disk based on who needs access to the file: Laravel’s included public disk is intended for publicly accessible files, while other configured disks can meet different storage needs. The filesystem documentation describes disks and file visibility.

Laravel’s validation rules apply after the request reaches the framework. PHP can impose separate upload limits. Web servers can impose them too, as can proxies and hosting providers. Check those limits when a request is rejected before Laravel returns validation errors.

What I'm building

Delegate tasks. Get software.

Give Vroni a GitHub issue, bug report, spec, or rough idea. It reads the repo, plans the change, writes code, runs checks, and works toward a review-ready pull request.

Take a look at vroni.com

Email updates

Usually a new article and a few links I found interesting.

No spam. Unsubscribe with one click.

Leave a Reply

Your email address will not be published. Required fields are marked *