如何在Laravel中验证数组?

200

我尝试在Laravel中验证数组POST:

$validator = Validator::make($request->all(), [
    "name.*" => 'required|distinct|min:3',
    "amount.*" => 'required|integer|min:1',
    "description.*" => "required|string"
             
]);

我发送了一个空的POST请求,得到了这样的结果if ($validator->fails()) {},它的返回值是False。这意味着验证通过了,但实际上并没有。

在Laravel中如何验证数组?当我提交一个包含input name="name[]"的表单时。

7个回答

449

星号符号 (*) 用于检查数组中的 ,而不是数组本身。

$validator = Validator::make($request->all(), [
    "names"    => "required|array|min:3",
    "names.*"  => "required|string|distinct|min:3",
]);

在上面的例子中:

  • “names”必须是至少具有3个元素的数组,
  • “names”数组中的values必须是不同(唯一)的字符串,长度至少为3个字符。

编辑:自Laravel 5.5以来,您可以直接在请求对象上调用validate()方法,如下所示:

$data = $request->validate([
    "name"    => "required|array|min:3",
    "name.*"  => "required|string|distinct|min:3",
]);

1
如果您正在使用 $request->validate([...]),请记得将其放置在 try catch 中。如果数据未通过验证,将会引发异常。 - daisura99
如何获取特定字段的错误信息?比如我有两个名称字段,而只有第二个字段出现了错误,我该如何获取它的错误信息? - Eem Jee
2
不需要在“name.*”上进行验证,因为它只会验证它是否存在。 - Ben Gooding
1
这太棒了。我想知道为什么在官方的数组验证文档中没有这方面的例子。 - Binar Web
1
如何显示消息,例如 $validator = Validator :: make($ request-> all(),[     “names”=>“required | array | min:3”,     “names。*”=>“required | string | distinct | min:3”, ],[name.required =>“您忘记填写此名称” ]);这样正确吗?如果是,则对我不起作用。 - Mohammad Fahad Rao
这不是一个有用的解决方案。在应用给定的解决方案后,当我提交表单时,由于我有2个名称元素作为数组,错误消息显示为“需要填写名称.1字段”、“需要填写名称.2字段”。这是用户友好的消息吗? - Kamlesh

84

我有一个HTML+Vue.js数据表格,这是我请求数据的数组:

[0] => Array
    (
        [item_id] => 1
        [item_no] => 3123
        [size] => 3e
    )
[1] => Array
    (
        [item_id] => 2
        [item_no] => 7688
        [size] => 5b
    )

使用此功能进行验证,以确保其正常工作:

$this->validate($request, [
    '*.item_id' => 'required|integer',
    '*.item_no' => 'required|integer',
    '*.size'    => 'required|max:191',
]);

回答不错,但我有这样的数组,我的表单有相同名称的单选按钮,当我提交时,由于单选按钮共享名称,我会收到验证错误。 - Theodory

36

编写验证和授权逻辑的推荐方式是将该逻辑放在单独的请求类中。这样,您的控制器代码将保持干净。

您可以通过执行php artisan make:request SomeRequest来创建一个请求类。

在每个请求类的rules()方法中定义您的验证规则:

//SomeRequest.php
public function rules()
{
   return [
    "name"    => [
          'required',
          'array', // input must be an array
          'min:3'  // there must be three members in the array
    ],
    "name.*"  => [
          'required',
          'string',   // input must be of type string
          'distinct', // members of the array must be unique
          'min:3'     // each string must have min 3 chars
    ]
  ];
}

在您的控制器中,编写路由函数如下所示:
// SomeController.php
public function store(SomeRequest $request) 
{
  // Request is already validated before reaching this point.
  // Your controller logic goes here.
}

public function update(SomeRequest $request)
{
  // It isn't uncommon for the same validation to be required
  // in multiple places in the same controller. A request class
  // can be beneficial in this way.
}

每个请求类都带有预先和后置验证钩子/方法,可以根据业务逻辑和特殊情况进行自定义,以修改请求类的正常行为。
您可以为类似类型的请求(例如webapi)创建父请求类,然后在这些父类中封装一些常见的请求逻辑。

25

有点更复杂的数据,是@Laran和@Nisal Gunawardana答案的混合

[ 
   {  
       "foodItemsList":[
    {
       "id":7,
       "price":240,
       "quantity":1
                },
               { 
                "id":8,
                "quantity":1
               }],
        "price":340,
        "customer_id":1
   },
   {   
      "foodItemsList":[
    {
       "id":7,
       "quantity":1
    },
    { 
        "id":8,
        "quantity":1
    }],
    "customer_id":2
   }
]

验证规则将会是:

 return [
            '*.customer_id' => 'required|numeric|exists:customers,id',
            '*.foodItemsList.*.id' => 'required|exists:food_items,id',
            '*.foodItemsList.*.quantity' => 'required|numeric',
        ];

3

您需要遍历输入数组,并为每个输入添加规则,如此处所述:遍历规则

以下是一些代码:

$input = Request::all();
$rules = [];

foreach($input['name'] as $key => $val)
{
    $rules['name.'.$key] = 'required|distinct|min:3';
}

$rules['amount'] = 'required|integer|min:1';
$rules['description'] = 'required|string';

$validator = Validator::make($input, $rules);

//Now check validation:
if ($validator->fails()) 
{ 
  /* do something */ 
}

15
不需要这样做-https://laravel.com/docs/5.4/validation#validating-arrays。 - Filip Sobol

1

在我的情况下,它运行良好。

$validator = Validator::make($request->all(), [
    "names" => "required|array|min:3",
    "*.names"=> "required|string|distinct|min:3",
]);

1
下面的代码对从Ajax调用返回的数组在我的情况下有效。
  $form = $request->input('form');
  $rules = array(
            'facebook_account' => 'url',
            'youtube_account' => 'url',
            'twitter_account' => 'url',
            'instagram_account' => 'url',
            'snapchat_account' => 'url',
            'website' => 'url',
        );
        $validation = Validator::make($form, $rules);

        if ($validation->fails()) {
            return Response::make(['error' => $validation->errors()], 400);
        }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接