array

Validates that a field is a PHP array and, when keys are listed, that it contains no unexpected keys.

Signature
array  |  array:key,key,...

Parameters

ParameterTypeDescription
$keyoptionalstringZero or more allowed key names, comma separated. Every key present in the input array must appear in this list; keys in the list may be absent.

Errors

Nothing on its own — a violation is recorded as a message, and validate() on a failing validator throws Illuminate\Validation\ValidationException.

array asserts that the field is a PHP array. Given parameters, it also becomes an allow-list: every key present in the input array must appear in the list you supplied. In the documentation's example, 'user' => 'array:name,username' rejects the input because it also carries an admin key.

When to reach for it

  • Any repeated field — tags[], line items, a list of ids.
  • A nested object in a JSON body, where you want to fix the shape of the object.
  • Anywhere you mass-assign the validated data and an unexpected key would become an unexpected column write. The docs are blunt about this: in general, always specify the allowed keys.

What trips people up

The key list is an allow-list, not a requirement list. array:name,username passes on an empty array — to demand a key, add a rule for it, such as 'user.name' => 'required'.

The check applies only one level deep, to the immediate keys of that field. Nested structures need their own rules with dot paths, and elements of a list need the * wildcard, as in 'items.*.sku'.

Finally, when an unexpected key is what failed, the message you get is still "The user field must be an array", which reads as nonsense to the user. Supply a custom message for that field.

Example

Example · php
<?php

use Illuminate\Support\Facades\Validator;

$input = [
    'user' => [
        'name'     => 'Taylor Otwell',
        'username' => 'taylorotwell',
        'admin'    => true,
    ],
];

$validator = Validator::make($input, [
    'user' => 'array:name,username',
]);

print_r($validator->errors()->toArray());

// Array
// (
//     [user] => Array
//         (
//             [0] => The user field must be an array.
//         )
// )

// The admin key is not in the allowed list, so the whole field fails.

When to use it

  • Lock a nested user object to a known set of keys before mass assignment.
  • Validate a tags[] multi-select from a form with a wildcard rule per element.
  • Check a JSON order payload's line items, each with a sku and a quantity.
  • Reject an extra role or is_admin key smuggled into a profile update.

Frequently asked questions

How do I reject unexpected keys in a Laravel array field?

Pass the allowed keys to the rule, as in 'user' => 'array:name,username'. Any key present in the input that is not in that list fails the field, which is why the documentation recommends always listing the keys you accept.

Does array:name,username require both keys to be present?

No — it is an allow-list, not a requirement list, so an empty array passes. Add explicit rules such as 'user.name' => 'required' for the keys that must exist.

How do I validate every item in an array?

Use the * wildcard in the field path: 'items' => ['required', 'array'] alongside 'items.*.sku' => ['required', 'string']. Each element is validated separately and error keys come back as items.0.sku, items.1.sku and so on.

More examples

Wildcards for list elements

Three levels at once: the list itself is bounded with min and max, each element is locked to two keys with array:sku,quantity, and each key gets its own rule through the * wildcard. The custom message replaces the confusing default "must be an array" text that an unexpected key would otherwise produce.

Example · php
<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class StoreOrderRequest extends FormRequest
{
    public function rules(): array
    {
        return [
            'items'            => ['required', 'array', 'min:1', 'max:50'],
            'items.*'          => ['array:sku,quantity'],
            'items.*.sku'      => ['required', 'string', 'regex:/^[A-Z]{2}-\d{4}$/'],
            'items.*.quantity' => ['required', 'integer', 'min:1'],

            'tags'   => ['sometimes', 'array', 'max:5'],
            'tags.*' => ['string', 'distinct', 'max:30'],
        ];
    }

    public function messages(): array
    {
        return [
            'items.*.array' => 'Each line item may only contain a sku and a quantity.',
        ];
    }
}

An allow-list does not require the keys

Only the unexpected key fails. If name must actually be present you need a separate rule such as 'user.name' => ['required', 'string'] — the key list never makes anything mandatory.

Example · php
<?php

use Illuminate\Support\Facades\Validator;

$cases = [
    'both keys' => ['name' => 'Ada', 'username' => 'ada'],
    'one key'   => ['name' => 'Ada'],
    'empty'     => [],
    'extra key' => ['name' => 'Ada', 'admin' => true],
];

foreach ($cases as $label => $user) {
    $passes = Validator::make(
        ['user' => $user],
        ['user' => 'array:name,username']
    )->passes();

    echo str_pad($label, 10), $passes ? "pass\n" : "fail\n";
}

// both keys pass
// one key   pass
// empty     pass
// extra key fail

Discussion

  • Be the first to comment on this lesson.