16

I have forms that submit multidimensional arrays. Like:

slide[1][title]
slide[2][title]

Now I use a Request class to define my rules. How can I loop through all array items within this class. I tried:

public function rules()
{
    return [
        'id' => 'required',
        'slide' => 'array|min:1',
        'slide.*.title' => 'required|max:255',
        'slide.*.description' => 'required|max:255',
    ];
}

But it did not work.

2

4 Answers 4

19

Laravel 5.5 or newer

You can use the same array validation syntax that is available in the Validator, so the code in the question now works:

public function rules()
{
    return [
        'id' => 'required',
        'slide' => 'array|min:1',
        'slide.*.title' => 'required|max:255',
        'slide.*.description' => 'required|max:255',
    ];

}

Laravel 5.4 or older

Disclaimer: This solution was posted in the question by Alexej. Since answers shouldn't be shared in the question body and the OP seems to be inactive, I repost his answer as a community wiki for future readers:

I've found the solution by getting the slide array and loop through it.

public function rules()
{
    $rules = [
        'id' => 'required',
        'slide' => 'array|min:1',
    ];
    foreach($this->request->get('slide') as $key => $val){
        $rules['slide.'.$key.'.title'] = 'required|max:255';
        $rules['slide.'.$key.'.description'] = 'required|max:255';
    }
    return $rules;
}
Sign up to request clarification or add additional context in comments.

3 Comments

Can any body explain, how to retrieve validated data after this as with $data = $request->validated(); I am getting only id and slide and not the title and description .
This solution is outdated for current versions of Laravel. You no longer need to specify the index for each rule in a multidimensional array. A * wildcard can now be used. See solution below for later Laravel versions.
@McWayWeb Not really outdated, but there is indeed a better way to do it. Basically the code in the question now works, so I updated the answer with that.
2

There is a better way to do this now. I'm not sure the exact minimum version of Laravel that supports this but I'm running 5.5 and this approach works.

Assuming you have request data like:

index:0
is_required:1
type:select
name:favorite color
title:What is your favorite color?
meta[0][key]:subtitle
meta[0][value]:If you have multiple favorites, pick your favorite-favorite.
meta[1][key]:default_value
meta[1][value]:Pink
options[0][index]:0
options[0][value]:Red
options[1][index]:3
options[1][value]:Pink
options[2][index]:1
options[2][value]:Blue
options[3][index]:2
options[3][value]:Green

Your validation rules can look like:

return [
    'index' => 'required|integer|min:0',
    'is_required' => 'required|boolean',
    'type' => [
        'required',
        Rule::in($this->types_enum)
    ],
    'name' => 'required|string|max:64',
    'meta' => 'sometimes|array',
    'meta.*.key' => 'required|string|max:64',
    'meta.*.value' => 'required|string',
    'options' => 'sometimes|array',
    'options.*.index' => 'required|integer|min:0',
    'options.*.value' => 'required|string',
];

Note the trick is just to use the wildcard operator (*) with dot notation to represent the index value of the array item itself.

Comments

0

There's no preconfigured validation rule for multidimensional arrays. The easist way is to do the array validation inside your controller.

The problem is when you use multidimensional array to store single values, then the logic is wrong and what you should fix is your logic, not the framework.

For instance, I saw lots of time sending the user credentials like $var['login']['pass'] and $var['login']['username'], which it could be translated easily to 2 different variables, which would make more sense.

In case you know what those values should be and you feel confident that the validation could be something generic for all different values, you can create a custom validator (read validation documentation of your laravel version).

Referring to your code I think multidimensional array is declared the same way as in your html slide[]['title']. It'll be beneficial to know how you are sending those parameters to the backend, to then be able to give you a clue about how to set up the validation.

Comments

0

Another way to validate multidimenssional array is:

<input name="horario[turno_id][]"> 

In your Controller:

$this->validate($request, 
[
 "horario.turno_id" => "required|array",
 "horario.turno_id.*" => "required",
],      
[
'horario.turno_id.required' => 'your message here',
]

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.