Laravel 4 Validation - Nested Indexed Arrays?

后端 未结 3 1936
孤城傲影
孤城傲影 2021-01-02 08:38

I have an array of various things...

$foo = [];
$foo[\'stuff\'][\'item\'][0][\'title\' => \'flying_lotus\'];
$foo[\'stuff\'][\'item\'][1][\'title\' =>          


        
相关标签:
3条回答
  • 2021-01-02 09:05

    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.

    0 讨论(0)
  • 2021-01-02 09:09

    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);
    
    0 讨论(0)
  • 2021-01-02 09:15

    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

    0 讨论(0)
提交回复
热议问题