between

Requires a size between two inclusive bounds, measured by the field's own type.

Signature
between:min,max

Parameters

ParameterTypeDescription
$minint|floatThe lower bound, inclusive.
$maxint|floatThe upper bound, inclusive.

Errors

Nothing on its own; a failure surfaces as Illuminate\Validation\ValidationException when run through validate() or a form request.

The field under validation must have a size between the given min and max (inclusive). Strings, numerics, arrays and files are evaluated in the same fashion as the size rule, so the two numbers mean characters, magnitude, element count or kilobytes depending on the field's type.

Both ends are inclusive

between:1,5 accepts 1 and accepts 5. If you need an exclusive bound there is no variant — use gt and lt, or adjust the numbers.

Same numeric trap as min and max

Without numeric or integer in the rule list, between measures string length. 'rating' => 'between:1,5' against posted input accepts any one- to five-character string, including "abcde" and "99999". Write 'rating' => 'integer|between:1,5'.

between or min plus max?

They produce the same outcome. The difference is the error message: between emits one message naming both bounds, while min:8|max:64 emits whichever bound was crossed. For a password field the separate messages are usually more helpful; for a numeric range a single message reads better.

between is not implicit, so an absent or empty field skips it. Pair it with required.

Example

Example · php
<?php

use Illuminate\Support\Facades\Validator;

$rules = ['rating' => ['required', 'integer', 'between:1,5']];

foreach ([0, 1, 3, 5, 6] as $rating) {
    $passes = Validator::make(['rating' => $rating], $rules)->passes();

    echo $rating . ' => ' . ($passes ? 'passes' : 'FAILS') . PHP_EOL;
}

// 0 => FAILS
// 1 => passes    <- lower bound is inclusive
// 3 => passes
// 5 => passes    <- upper bound is inclusive
// 6 => FAILS

When to use it

  • Constraining a star rating to 1 through 5 on a review form.
  • Requiring a username of 3 to 20 characters.
  • Accepting between 2 and 10 poll options in a submitted array.
  • Limiting an uploaded document to a 10 KB to 5 MB window.

Frequently asked questions

Is between inclusive of its bounds?

Yes, both ends are inclusive — `between:1,5` accepts 1 and 5. There is no exclusive variant; use `gt:0` and `lt:6`, or simply shift the bounds, when you need to exclude an endpoint.

Should I use between or min and max?

They validate identically, so pick on message quality. `between` produces one message naming both bounds, which reads well for numeric ranges; `min` and `max` produce a message about the specific bound crossed, which is usually more actionable for string lengths.

Why does between:1,5 accept the word "abcde"?

Because without `numeric` or `integer` in the rule list, `between` measures string length, and "abcde" is five characters. Add the type rule first: `'rating' => 'integer|between:1,5'`.

More examples

Without a numeric rule, between measures length

The first and third calls pass for the same reason: both values are five characters long. This is the single most common misuse of `between`, and it fails open rather than closed, so nothing in the application complains until bad data reaches the database.

Example · php
<?php

use Illuminate\Support\Facades\Validator;

$posted = ['rating' => '99999'];   // five characters

// No integer rule: strlen("99999") is 5, which is within 1..5.
var_dump(Validator::make($posted, ['rating' => 'between:1,5'])->passes());

// With integer: 99999 is compared numerically and rejected.
var_dump(Validator::make($posted, ['rating' => 'integer|between:1,5'])->passes());

// The same rule set also lets a word through:
var_dump(Validator::make(['rating' => 'abcde'], ['rating' => 'between:1,5'])->passes());

// bool(true)   <- the silent bug
// bool(false)
// bool(true)   <- and so does this

between versus min plus max — the messages differ

The check is identical; only the wording changes. `between` states the whole range, which suits a numeric field where the user needs to know both ends. `min`/`max` names the bound that was actually crossed, which is usually clearer for text length.

Example · php
<?php

use Illuminate\Support\Facades\Validator;

$short = ['username' => 'ab'];

$a = Validator::make($short, ['username' => 'string|between:3,20']);
$b = Validator::make($short, ['username' => 'string|min:3|max:20']);

print_r($a->errors()->all());
print_r($b->errors()->all());

// Array
// (
//     [0] => The username field must be between 3 and 20 characters.
// )
// Array
// (
//     [0] => The username field must be at least 3 characters.
// )

between on arrays and files

Three different meanings of `between` in one rule set: 10 to 255 characters for the question, 2 to 10 elements for the options array, and 10 KB to 5 MB for the file. The `nullable` on the attachment matters — without it, an omitted file would still be skipped, but a blank posted value converted to null would fail the `file` rule.

Example · php
<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class StorePollRequest extends FormRequest
{
    public function rules(): array
    {
        return [
            'question'   => ['required', 'string', 'between:10,255'],
            'options'    => ['required', 'array', 'between:2,10'],
            'options.*'  => ['required', 'string', 'max:120'],
            'attachment' => ['nullable', 'file', 'between:10,5120'],
        ];
    }
}

// print_r($request->validated()['options']);
//
// Array
// (
//     [0] => Yes
//     [1] => No
// )

Discussion

  • Be the first to comment on this lesson.