required

Requires the field to be present and not null, an empty string, an empty array or a pathless upload.

Signature
required

Errors

Nothing on its own; when the rule set is run through validate() or a form request, a failure raises Illuminate\Validation\ValidationException.

The field under validation must be present in the input data and not empty. Laravel treats a value as empty when it is null, an empty string, an empty array or empty Countable, or an uploaded file with no path. A string of only whitespace is empty too — the check trims before comparing.

What is not empty

The integer 0, the string "0", false, and an array containing a single empty string all pass. This surprises people writing 'quantity' => 'required' and expecting zero to be rejected; use min:1 for that.

Where people get bitten

Laravel's global middleware includes ConvertEmptyStringsToNull, so a blank text input arrives as null. Either way required rejects it, but that is why the field you can see in the payload still fails.

Unchecked HTML checkboxes are never submitted at all, so required on one always fires. Use accepted for consent boxes.

required is an implicit rule: it runs even when the attribute is absent. Almost every other rule — email, unique, min — silently skips absent or empty values, which is why 'email' => 'email' alone lets an empty payload through.

If you need "present but may be blank", combine present with nullable instead.

Example

Example · php
<?php

use Illuminate\Support\Facades\Validator;

$validator = Validator::make(
    ['name' => '', 'tags' => [], 'quantity' => 0],
    [
        'name'     => 'required',
        'tags'     => 'required',
        'quantity' => 'required',
    ]
);

var_dump($validator->fails());
print_r($validator->errors()->keys());

// bool(true)
// Array
// (
//     [0] => name
//     [1] => tags
// )
//
// quantity passes: integer 0 is not "empty".

When to use it

  • Rejecting a sign-up submission where the name box was left blank.
  • Guaranteeing an API POST body carries an order_id before any database work starts.
  • Making a document upload mandatory on a claims submission endpoint.
  • Ensuring a multi-select sends at least one option rather than an empty array.

Frequently asked questions

Why does required pass when the value is 0 or false?

Because neither is on Laravel's empty list — only null, an empty string, an empty array or Countable, and a pathless uploaded file count as empty. To reject zero, add a rule that expresses the real constraint: `integer|min:1` for a quantity, `accepted` for a checkbox that must be ticked.

What is the difference between required and nullable?

They are opposites: `required` rejects null, `nullable` permits it. They should never appear on the same field. If you want a field that may be omitted entirely, use `sometimes` rather than `nullable`, since most rules already skip absent keys.

Why does my required checkbox always fail validation?

An unchecked checkbox is not submitted by the browser at all, so the field is absent and `required` fires. Use the `accepted` rule for terms-of-service boxes, or render a hidden input with value 0 immediately before the checkbox so something is always posted.

More examples

Exactly what counts as empty

The four failing cases are exactly the four the documentation lists (null, empty string, empty array, pathless file), plus whitespace-only strings which are trimmed before the check. Note that `false` and `0` pass — if a boolean toggle must be explicitly sent, `required|boolean` is right, but if it must be true you want `accepted`.

Example · php
<?php

use Illuminate\Support\Facades\Validator;

$cases = [
    'null'          => null,
    'empty string'  => '',
    'only spaces'   => '   ',
    'integer zero'  => 0,
    'string zero'   => '0',
    'false'         => false,
    'empty array'   => [],
    'array of one'  => [''],
];

foreach ($cases as $label => $value) {
    $passes = Validator::make(['v' => $value], ['v' => 'required'])->passes();

    echo str_pad($label, 14) . ($passes ? 'passes' : 'FAILS') . PHP_EOL;
}

// null          FAILS
// empty string  FAILS
// only spaces   FAILS
// integer zero  passes
// string zero   passes
// false         passes
// empty array   FAILS
// array of one  passes

required inside a form request, including array members

`tags => required|array|min:1` rejects both a missing key and an empty array, while `tags.* => required` rejects an array that contains blank entries such as `['php', '']`. Without the `tags.*` line, `['']` would pass because it has a count of one.

Example · php
<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class StorePostRequest extends FormRequest
{
    public function rules(): array
    {
        return [
            'title'  => ['required', 'string', 'max:255'],
            'body'   => ['required', 'string'],
            'cover'  => ['required', 'file', 'max:2048'],
            'tags'   => ['required', 'array', 'min:1'],
            'tags.*' => ['required', 'string', 'max:40'],
        ];
    }
}

// In the controller:
//
// public function store(StorePostRequest $request)
// {
//     $validated = $request->validated();
//
//     echo $validated['title'];
//     print_r($validated['tags']);
// }

Present but allowed to be blank

This is the distinction people usually want when they reach for `required` and then fight it. `present` asserts the key exists in the payload; `nullable` permits its value to be null. `required` is the union of both plus a non-emptiness check.

Example · php
<?php

use Illuminate\Support\Facades\Validator;

// "required" rejects a null nickname.
$a = Validator::make(['nickname' => null], ['nickname' => 'required']);

// "present|nullable" insists the key is sent, but allows it to be blank.
$b = Validator::make(['nickname' => null], ['nickname' => 'present|nullable|string']);

// The key is missing entirely, so "present" fails.
$c = Validator::make([], ['nickname' => 'present|nullable|string']);

var_dump($a->passes()); // bool(false)
var_dump($b->passes()); // bool(true)
var_dump($c->passes()); // bool(false)

Discussion

  • Be the first to comment on this lesson.