如何在 Laravel 中验证数组?

Posted

技术标签:

【中文标题】如何在 Laravel 中验证数组?【英文标题】:How to validate array in Laravel? 【发布时间】:2017-07-04 15:12:31 【问题描述】:

我尝试在 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。这意味着验证是正确的,但事实并非如此。

当我使用input name="name[]"提交表单时

【问题讨论】:

【参考方案1】:

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

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

在上面的例子中:

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

编辑:从 Laravel 5.5 开始,您可以像这样直接在 Request 对象上调用 validate() 方法:

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

【讨论】:

如果你使用$request->validate([...]),记得把它放在try catch中。如果数据未通过验证,将引发异常。 如何获取特定字段的错误信息?就像我有 2 个名称字段,然后它是只有错误的第二个字段,我该如何获得它? 不需要'name.*' 上的必需项,因为它仅在存在时对其进行验证 这太棒了。我想知道为什么official documentation of array validation 中没有这样的例子。 如何显示消息然后例如 $validator = Validator::make($request->all(), [ "names" => "required|array|min:3", "names. *" => "required|string|distinct|min:3", ],[ name.required=>"你留下了这个名字" ]);这是正确的吗 ?如果是,那么它对我不起作用【参考方案2】:

我将此数组作为来自 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',
]);

【讨论】:

不错的答案,但我有这样的数组,而且我的表单有同名的单选按钮,当我提交时,由于单选按钮共享名称,我得到了验证错误。【参考方案3】:

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

你可以通过执行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)创建父请求类,然后​​在这些父类中封装一些常见的请求逻辑。

【讨论】:

【参考方案4】:

更复杂的数据,@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',
        ];

【讨论】:

【参考方案5】:

您必须循环输入数组并为每个输入添加规则,如下所述:Loop Over Rules

这是给你的一些代码:

$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 */ 

【讨论】:

没有必要这样做 - laravel.com/docs/5.4/validation#validating-arrays【参考方案6】:

下面的代码适用于来自 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);
        

【讨论】:

以上是关于如何在 Laravel 中验证数组?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Laravel 验证中要求数组并防止获得意外的键

如何在 laravel 中输入所有数组并在字段下方显示验证错误

如何在 Vue.js 中显示错误数组?使用 Laravel 进行后端验证

Vuejs如何显示laravel输入数组验证错误

如何验证 laravel 中的复选框数组?

Laravel 验证 - 如何检查给定数组中是不是存在值?