Andreas Hunter
Andreas Hunter

Reputation: 5004

Laravel array key validation

I have custom request data:

{
    "data": {
        "checkThisKeyForExists": [
            {
                "value": "Array key Validation"
            }
        ]
    }
}

And this validation rules:

$rules = [
    'data' => ['required','array'],
    'data.*' => ['exists:table,id']
];

How I can validate array key using Laravel?

Upvotes: 1

Views: 4288

Answers (3)

Atif Mahmood
Atif Mahmood

Reputation: 390

maybe it will helpful for you

$rules = ([
    'name' => 'required|string',    //your field
    'children.*.name' => 'required|string',    //your 1st nested field
    'children.*.children.*.name' => 'required|string'    //your 2nd nested field
]);

Upvotes: 3

Moritz Friedrich
Moritz Friedrich

Reputation: 1471

The right way
This isn't possible in Laravel out of the box, but you can add a new validation rule to validate array keys:

php artisan make:rule KeysIn

The rule should look roughly like the following:

class KeysIn implements Rule
{
    public function __construct(protected array $values)
    {
    }

    public function message(): string
    {
        return ':attribute contains invalid fields';
    }

    public function passes($attribute, $value): bool
    {
        // Swap keys with their values in our field list, so we
        // get ['foo' => 0, 'bar' => 1] instead of ['foo', 'bar']
        $allowedKeys = array_flip($this->values);

        // Compare the value's array *keys* with the flipped fields
        $unknownKeys = array_diff_key($value, $allowedKeys);

        // The validation only passes if there are no unknown keys
        return count($unknownKeys) === 0;
    }
}

You can use this rule like so:

$rules = [
    'data' => ['required','array', new KeysIn(['foo', 'bar'])],
    'data.*' => ['exists:table,id']
];

The quick way
If you only need to do this once, you can do it the quick-and-dirty way, too:

$rules = [
    'data' => [
        'required',
        'array',
        fn(attribute, $value, $fail) => count(array_diff_key($value, $array_flip([
            'foo',
            'bar'
        ]))) > 0 ? $fail("{$attribute} contains invalid fields") : null
    ],
    'data.*' => ['exists:table,id']
];

Upvotes: 4

Sallmin Rexha
Sallmin Rexha

Reputation: 125

I think this is what you are looking:

$rules = [
   'data.checkThisKeyForExists.value' => ['exists:table,id']
];

Upvotes: 0

Related Questions