I have an array of various things...
$foo = [];
$foo[\'stuff\'][\'item\'][0][\'title\' => \'flying_lotus\'];
$foo[\'stuff\'][\'item\'][1][\'title\' =>
The following answer is for Laravel <= 5.1. Laravel 5.2 introduced built-in array validation.
At this time, the Validator class isn't meant to iterate over array data. While it can traverse through a nested array to find a specific value, it expects that value to be a single (typically string
) value.
The way I see it, you have a few options:
1: Create rules with the array key in the field name.
Basically essentially what you're doing already, except you'd need to figure out exactly how many values your ['stuff']['item']
array has. I did something like this with good results:
$data = [
'stuff' => [
'item' => [
['title' => 'flying_lotus'],
['title' => 'various_cheeses'],
['title' => ''],
['title' => 'welsh_cats'],
]
]
];
$rules = [];
for ($i = 0, $c = count($data['stuff']['item']); $i < $c; $i++)
{
$rules["stuff.item.{$i}.title"] = 'required';
}
$v = Validator::make($data, $rules);
var_dump($v->passes());
2: Create a custom validation method.
This will allow you to create your own rule, where you can expect an array value and iterate it over as necessary.
This method has its caveats, in that A) you won't have specific value error messages, since it'll error for the entire array (such as if you pass stuff.item
as the value to check), and B) you'll need to check all of your array's possible values in your custom function (I'm assuming you'll have more than just title
to validate).
You can create the validation method by using the Validator::extend() or by fully extending the class somewhere else.
3: Extend the Validator class and replace/parent the rules in question to accept arrays.
Create your own extended Validator class, and either implement custom rules, or rename existing ones, enabling those rules to accept an array value if one happens along. This has some similar caveats to the #2 custom rule option, but may be the "best practice" if you intend on validating iterated arrays often.
In addition to @Cryode answer, and for my laravel 5 issue.
my form has an database id index. so my form fields have the index
$foo['stuff']['item'][8]['title' => 'flying_lotus'];
$foo['stuff']['item'][12]['title' => 'various_cheeses'];
$foo['stuff']['item'][23]['title' => 'the_career_of_vanilla_ice'];
i used foreach to reach my goal
foreach($request->input()['stuff']['items'] as $key => $value){
$rules["stuff.items.{$key}.title"] = 'required';
}
and the custom error messages
foreach($request->input()['stuff']['items'] as $key => $value){
$messages["stuff.items.{$key}.title.required"] = 'Each Title is required...';
}
and validate
Validator::make($request->input(), $rules, $messages);
As @Cryode said, Laravel doesn't currently offer this functionality out of the box. I created a class extending the default Laravel Validator to add an iterate($attribute, $rules, $messages)
method.
It can also iterate recursively through arrays so that (for example) if you have any number of "books", each of which may have any number of "citations", this will still work, which @Cryode's example does not do, so this is a little more robust.
https://github.com/penoonan/laravel-iterable-validator