假设我们具有以下表单数据:
{age: 15, father: "John Doe"}
我们想要基于同一项目的其他数据来验证father
字段背后有一些复杂的逻辑(对于此示例,我们希望在年龄<18岁时验证父亲至少有5个字符)。 / p>
可以这样做:
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']
我现在的问题是轻松地为每个项目的sometimes
字段表达father
规则,这取决于项目的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
回调中的项目。但这似乎不是很优雅:(
答案 0 :(得分:2)
无法使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'
];
}
好奇地了解如何进行改进。
答案 1 :(得分:1)
我可以使用的最短的方法是:
"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");