Laravel表单验证 - MessageBag中没有用于输入数组的数组索引

时间:2014-12-24 22:29:59

标签: php laravel laravel-4 laravel-validation

我有一个输入“数组”的表单,在提交时,使用Laravel的Validator.

进行验证

验证按预期工作,将规则应用于每个数组元素,并相应地返回错误的MessageBag。

问题:MessageBag没有引用数组的相关索引。 有没有办法(除了为数组的每个可能的索引定义规则)以使Laravel引用相关的输入数组索引?

示例HTML

<input name="something[]" type="text" />
<input name="something[]" type="text" />
<input name="something[]" type="text" />
...

示例验证器

Validator::make
(
    Input::all(),
    array
    (
        "something" => array("required", "exists:somewhere")
    )
);

验证后的示例MessageBag (不引用输入数组索引)

object(Illuminate\Support\MessageBag)#150 (2)
{
    ["messages":protected]=> array(6)
    {
        ["something"]=> array(1)
        {
            [0]=> string(26) "Some error message"
        }
    }
    ...
}

2 个答案:

答案 0 :(得分:1)

我没有找到使用标准Laravel核心功能的任何方法,所以我最终扩展了Validator类来实现解决方案。

为了更好地理解此解决方案,请记录下面的代码。

  1. 创建app/libraries/MyApp/Validation目录以保存新类

  2. 根据本文的扩展\Illuminate\Validation\Validator(“从类中解析”方法):Extending the Laravel 4 Validator

  3. 覆盖Validator#passes()

    namespace MyApp\Validation;
    
    use \Illuminate\Validation\Validator;
    
    class ArrayAwareValidator extends Validator
    {
        //Override Validator#passes() method
        public function passes()
        {
            //For each validation rule...
            foreach ($this->rules as $attribute => $rules)
            {
                //Get the value to be validated by this rule
                $values = $this->getValue($attribute);
    
                //If the value is an array, we got an HTML input array in our hands
                if(is_array($values))
                {
                    //Iterate through the values of this array...
                    for($i=0; $i<count($values); $i++)
                    {
                        //...and create a specific validation rule for this array index
                        $this->rules[$attribute.".".$i] = $rules;
                    }
    
                    //Delete original rule
                    unset($this->rules[$attribute]);
                }
            }
    
            //Let Validator do the rest of the work
            return parent::passes();
        }
    }
    
  4. 这导致以下MessageBag

    object(Illuminate\Support\MessageBag)#151 (2)
    {
        ["messages":protected]=> array(2)
        {
            ["something.0"]=>
            array(1)
            {
              [0]=> string(26) "Some error message"
            }
            ["something.1"]=>
            array(1)
            {
              [0]=> string(26) "Some error message"
            }
        }
        ...
    }
    
  5. 客户端,使用JavaScript,我将名称从索引中拆分(例如“something.1”到“something”和“1”),然后使用此信息来识别正确的表单输入。我正在使用Ajax提交表单,因此您可能需要在此处使用不同的方法。

  6. 注意:这是一个实用的解决方案,适用于我的问题。如您所见,数组索引与输入名称一起传递在同一个字符串中。您可能希望进一步扩展以使Validator返回一个Object或一个名称和索引为不同的数组。

答案 1 :(得分:0)

你的验证员应该是这样的:

       Validator::make
 (
   Input::all(),
array
(
    'something' => 'required,unique:somewhere'
));