2

我有一个表单,它有一个输入“数组”,当提交时,它会使用 Laravel 的验证器进行验证。

验证按预期工作,将规则应用于每个数组元素,并相应地返回 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"
        }
    }
    ...
}
4

2 回答 2

1

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

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

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

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

  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 提交表单,因此您可能需要在此处使用不同的方法。

注意:这是一个实用的解决方案,非常适合我的问题。如您所见,数组索引与输入名称一起在同一字符串中传递。您可能希望对事物进行更多扩展,以Validator返回一个对象或数组,并将名称和索引作为单独的事物。

于 2014-12-26T19:23:19.707 回答
0

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

       Validator::make
 (
   Input::all(),
array
(
    'something' => 'required,unique:somewhere'
));
于 2014-12-25T12:21:25.630 回答