Laravel有时会对数组进行验证

wpx232ag  于 2023-08-08  发布在  其他
关注(0)|答案(3)|浏览(153)

假设我们有以下表单数据:

{age: 15, father: "John Doe"}

字符串
我们希望在基于同一项的其他数据验证father字段背后有一些复杂的逻辑(在本例中,我们希望在年龄< 18时验证father至少有5个字符)。
可以这样做:

Standard validation rules: ['age': 'required|integer']

$validator->sometimes('father', 'required|min:5', function($data) {
    return $data['age'] < 18;
});


现在,我们想用一个项目列表来做同样的事情。现在,我们有以下表单数据:

[
  {age: 25, },
  {age: 15, father: "John Doe"},
  {age: 40, },
]


通用验证规则现在如下所示:

['items.*.age': 'required|integer']


我现在的问题是轻松地表达每个项目的father字段的sometimes规则,该规则将取决于项目的age字段。

$validator->sometimes('items.*.father', 'required|min:5', function($data) {
    // Does not work anymore: return $data['age'] < 18;
    // Any way to know which item we are dealing with here?
});


我能想到的一种方法是在验证器after回调中循环这些项。但这似乎并不优雅:(

hmmo2u0o

hmmo2u0o1#

无法让sometimes()以您需要的方式工作。sometimes()不会在数组项上“循环”,它只被调用一次。
我想出了一个替代方法,它并不完美,但也许你会发现它很有用。

/**
 * Get the validation rules that apply to the request.
 *
 * @return array
 */
public function rules()
{
    Validator::extend('father_required_if_child', function ($attribute, $value, $parameters, $validator) {

        $childValidator = Validator::make($value, [
            'age' => 'required|integer'
        ]);

        $childValidator->sometimes('father', 'required|min:5', function($data) {
            return is_numeric($data['age']) && $data['age'] < 18;
        });

        if (!$childValidator->passes()) {
            return false;
        }

        return true;

        // Issue: since we are returning a single boolean for three/four validation rules, the error message might
        // be too generic.

        // We could also ditch $childValidator and use basic PHP logic instead.
    });

    return [
        'items.*' => 'father_required_if_child'
    ];
}

字符串
好奇地想知道如何改进。

jyztefdp

jyztefdp2#

我能找到的最短的工作方法是这样的:

"items" => "required|array",
"items.*.age" => "required|integer",
"items.*.father" => "required_if:object.*.age,".implode(",",range(0,18))."|min:5"

字符串
任何时候一个人需要一个父亲,它应该至少有5个字符。当一个人的年龄在18岁以下时,需要父亲。
required_if处理多个用逗号分隔的方程。因此,我将0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18写成implode(',',range(0,18))来获得该部分。
我使用的测试设置:

控制器(使用HomeController)

function posttest(Request $request) {
    $validator = Validator::make($request->all(), [
        "object" => "required|array",
        "object.*.age" => "required|integer",
        "object.*.father" => "required_if:object.*.age,".implode(",",range(0,18))."|min:5"
    ]);

    if($validator->fails()){
        dd($validator->errors());
    }
}

查看(test.blade.php)

@extends('layouts.app')
@section('content')
<form action="{{URL::to("/posttest")}}" method="POST">
@csrf
<input type="number" name="object[0][age]" value="12">
<input type="text" name="object[0][father]" value="John">
<input type="number" name="object[1][age]" value="15">
<input type="text" name="object[1][father]" value="John Doe">
<input type="number" name="object[2][age]" value="17">
<input type="submit" value="gönder">
</form>
@endsection

路线

Route::view("/test", "test");
Route::post('/posttest', "HomeController@posttest");

jogvjijk

jogvjijk3#

我使用Validator类的sometimes方法的回调函数的第二个参数的值来实现它。下面是我如何使用laravel 8完成的。

$validator->sometimes('father', 'required|min:5', function($data,$instance) {
    return $instance['age'] < 18;
});

字符串

相关问题