integer
Validates that a field is an integer as accepted by PHP's FILTER_VALIDATE_INT filter.
integer | integer:strictParameters
| Parameter | Type | Description |
|---|---|---|
$strictoptional | string | Literal flag. When present, only a value whose PHP type is integer passes; strings holding integer values are rejected. |
Errors
Nothing on its own — the failure is recorded as a message, and Illuminate\Validation\ValidationException is raised only by validate() on a failing validator.
Changelog
- PHP 12.xAdded the strict parameter (integer:strict), which rejects strings with integer values and passes only the integer type.
integer checks that a field is an integer in the sense PHP's FILTER_VALIDATE_INT filter means it: 42, "42", "-7" and "+3" pass; "4.5", "1e3", "42abc" and "" do not.
When to reach for it
- Route or query parameters that are database ids, page numbers or offsets.
- Counts and quantities that must not carry a fractional part.
- Enum-like numeric codes, usually alongside
in:1,2,3.
What trips people up
The framework documentation carries an explicit warning here: this rule does not verify the variable type, only that the value is of a type the integer filter accepts. Because FILTER_VALIDATE_INT is permissive about what it will coerce, the docs recommend combining it with numeric when you truly want "this is a number, and it is whole".
Second, nothing is cast. A field validated with integer still comes back from validated() as the string "42", which will make a strict comparison (===), a match arm, or a typed constructor argument behave differently from what you expect. Read it through $request->integer('quantity'), cast it in the model, or use integer:strict if the client should be sending a real JSON integer.
Example
<?php
use Illuminate\Support\Facades\Validator;
$validator = Validator::make([
'quantity' => '42',
'discount' => '4.5',
], [
'quantity' => ['required', 'integer', 'min:1'],
'discount' => ['nullable', 'integer'],
]);
print_r($validator->errors()->toArray());
// Array
// (
// [discount] => Array
// (
// [0] => The discount field must be an integer.
// )
// )
var_dump($validator->valid()['quantity']);
// string(2) "42" <- validated, but still a stringWhen to use it
- Guard a page or per_page query parameter before it reaches a paginator.
- Validate a quantity on an order line so a fractional value never reaches the database.
- Check a foreign key posted from a select box, paired with exists.
- Bound a numeric API version or code field with integer plus in.
Frequently asked questions
Why does the integer rule accept the string "42"?
Because the rule checks PHP's FILTER_VALIDATE_INT filter rather than the variable type, and form and query input always arrives as strings. Use integer:strict, added in Laravel 12, if you require a real integer type.
Does the integer validation rule cast the value to an int?
No. validated() returns the value unchanged, so "42" stays a string. Use $request->integer('field'), an explicit (int) cast, or an Eloquent cast on the model attribute.
Should I use integer or numeric for a quantity field?
Use both — ['required', 'numeric', 'integer'] — which is what the Laravel documentation recommends. numeric guarantees the value is a number and integer guarantees it has no fractional part.
More examples
Pairing integer with numeric
The documentation's own recommendation: state numeric alongside integer when the field must be a number as well as integer-shaped. perPage() shows the cast step — $request->integer() returns a real int with a fallback, so the paginator never receives a string.
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class ListOrdersRequest extends FormRequest
{
public function rules(): array
{
return [
'page' => ['sometimes', 'numeric', 'integer', 'min:1'],
'per_page' => ['sometimes', 'numeric', 'integer', 'between:1, 100'],
];
}
public function perPage(): int
{
return $this->integer('per_page', 25);
}
}Strict integer on a JSON endpoint
With strict, only the field whose PHP type is integer survives; "7" as a JSON string fails. Reserve this for machine-to-machine endpoints — an HTML form posts every field as a string, so integer:strict would reject all of them.
<?php
use Illuminate\Support\Facades\Validator;
$payload = json_decode('{"a": 7, "b": "7"}', true);
$validator = Validator::make($payload, [
'a' => ['integer:strict'],
'b' => ['integer:strict'],
]);
print_r($validator->errors()->keys());
// Array
// (
// [0] => b
// )Route model id in a controller
Shows integer used at two levels: on a foreign key before an exists lookup, and inside a wildcard path so every line item's quantity is checked. A failing validate() call throws ValidationException, which the framework turns into a 422 response for JSON clients.
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class InvoiceController extends Controller
{
public function store(Request $request)
{
$data = $request->validate([
'customer_id' => ['required', 'integer', 'exists:customers,id'],
'line_items' => ['required', 'array', 'min:1'],
'line_items.*.quantity' => ['required', 'integer', 'min:1'],
]);
echo count($data['line_items']), " line items accepted\n";
}
}
Discussion