如果值存在于另一个字段数组中,Laravel 验证规则
Posted
技术标签:
【中文标题】如果值存在于另一个字段数组中,Laravel 验证规则【英文标题】:Laravel Validation Rules If Value Exists in Another Field Array 【发布时间】:2017-08-26 03:11:26 【问题描述】:我在 Laravel 5.4 中工作,我需要稍微具体的验证规则,但我认为这应该很容易实现,而无需扩展类。只是不知道如何使这项工作..
如果program
数组包含'Music'
,我想做的是强制'music_instrument'
表单字段。
我找到了这个线程How to set require if value is chosen in another multiple choice field in validation of laravel?,但这不是一个解决方案(因为它一开始就没有得到解决),它不起作用的原因是提交的数组索引不是恒定的(未选中复选框在索引提交结果时不考虑...)
我的情况是这样的:
<form action="" method="post">
<fieldset>
<input name="program[]" value="Anthropology" type="checkbox">Anthropology
<input name="program[]" value="Biology" type="checkbox">Biology
<input name="program[]" value="Chemistry" type="checkbox">Chemistry
<input name="program[]" value="Music" type="checkbox">Music
<input name="program[]" value="Philosophy" type="checkbox">Philosophy
<input name="program[]" value="Zombies" type="checkbox">Zombies
<input name="music_instrument" type="text" value"">
<button type="submit">Submit</button>
</fieldset>
</form>
如果我从复选框列表中选择一些选项,我的 $request
值中可能会出现此结果
[program] => Array
(
[0] => Anthropology
[1] => Biology
[2] => Music
[3] => Philosophy
)
[music_instrument] => 'Guitar'
在这里查看验证规则:https://laravel.com/docs/5.4/validation#available-validation-rules 我认为像他这样的东西应该可以工作,但我实际上什么也没得到:
$validator = Validator::make($request->all(),[
'program' => 'required',
'music_instrument' => 'required_if:program,in:Music'
]);
我希望这也能奏效,但没有运气:
'music_instrument' => 'required_if:program,in_array:Music',
想法?有什么建议吗?
谢谢!
【问题讨论】:
【参考方案1】:我知道这篇文章较旧,但如果有人再次遇到此问题。
$validator = Validator::make($request->all(),[
'program' => 'required',
'music_instrument' => 'required_if:program,Music,other values'
]);
【讨论】:
【参考方案2】:这是我使用 Laravel 6 验证规则解决此类问题的一段代码
我尝试使用上面的代码
public function rules()
return [
"some_array_field.*" => ["required", "integer", "in:1,2,4,5"],
"another_field" => ["nullable", "required_if:operacao.*,in:1"],
];
我需要当 some_array_field 的值为 1 时,必须验证 another_field,否则,可以为空。
使用上面的代码,即使使用 required_if:operacao.*,1
如果我将 another_field 的规则更改为 required_if:operacao.0,1
WORKS 但仅当要查找的值在索引 0 中时,当订单更改时,验证将失败。
所以,我决定使用自定义闭包函数
这是我的示例的最终代码。
public function rules()
return [
"some_array_field.*" => ["required", "integer", "in:1,2,4,5"],
"another_field" => [
"nullable",
Rule::requiredIf (
function ()
return in_array(1, (array)$this->request->get("some_array_field"));
),
]
];
希望也能解决你的烦恼!
【讨论】:
【参考方案3】:您可以像这样创建一个名为 required_if_array_contains
的新自定义规则...
在 app/Providers/CustomValidatorProvider.php 添加一个新的私有函数:
/**
* A version of required_if that works for groups of checkboxes and multi-selects
*/
private function required_if_array_contains(): void
$this->app['validator']->extend('required_if_array_contains',
function ($attribute, $value, $parameters, Validator $validator)
// The first item in the array of parameters is the field that we take the value from
$valueField = array_shift($parameters);
$valueFieldValues = Input::get($valueField);
if (is_null($valueFieldValues))
return true;
foreach ($parameters as $parameter)
if (in_array($parameter, $valueFieldValues) && strlen(trim($value)) == 0)
// As soon as we find one of the parameters has been selected, we reject if field is empty
$validator->addReplacer('required_if_array_contains', function($message) use ($parameter)
return str_replace(':value', $parameter, $message);
);
return false;
// If we've managed to get this far, none of the parameters were selected so it must be valid
return true;
);
不要忘记检查 CustomValidatorProvider.php 顶部是否有 use
语句,以便我们在新方法中使用 Validator 作为参数:
...
use Illuminate\Validation\Validator;
然后在 CustomValidatorProvider.php 的 boot() 方法中调用你的新私有方法:
public function boot()
...
$this->required_if_array_contains();
然后通过在 resources/lang/en/validation.php 中的数组中添加一个新项来教 Laravel 以人性化的方式编写验证消息:
return [
...
'required_if_array_contains' => ':attribute must be provided when ":value" is selected.',
]
现在你可以像这样编写验证规则:
public function rules()
return [
"animals": "required",
"animals-other": "required_if_array_contains:animals,other-mamal,other-reptile",
];
在上面的示例中,animals
是一组复选框,animals-other
是一个文本输入,仅在选中 other-mamal
或 other-reptile
值时才需要。
这也适用于启用了多项选择的选择输入,或者任何在请求中的一个输入中产生一组值的输入。
【讨论】:
【参考方案4】:我针对类似问题采取的方法是在我的 Controller 类中创建一个私有函数,并在返回 true 时使用三元表达式添加所需字段。
在这种情况下,我有大约 20 个带有复选框以启用输入字段的字段,因此相比之下它可能有点过分,但随着您的需求增长,它可能会有所帮助。
/**
* Check if the parameterized value is in the submitted list of programs
*
* @param Request $request
* @param string $value
*/
private function _checkProgram(Request $request, string $value)
if ($request->has('program'))
return in_array($value, $request->input('program'));
return false;
使用此功能,如果您的其他程序也有其他字段,则可以应用相同的逻辑。
然后在store函数中:
public function store(Request $request)
$this->validate(request(), [
// ... your other validation here
'music_instrument' => ''.($this->_checkProgram($request, 'music') ? 'required' : '').'',
// or if you have some other validation like max value, just remember to add the |-delimiter:
'music_instrument' => 'max:64'.($this->_checkProgram($request, 'music') ? '|required' : '').'',
]);
// rest of your store function
【讨论】:
这是个好主意!谢谢【参考方案5】:没有尝试过,但在一般数组字段中,您通常会这样写:program.*
,所以也许这样的东西会起作用:
$validator = Validator::make($request->all(),[
'program' => 'required',
'music_instrument' => 'required_if:program.*,in:Music'
]);
如果它不起作用,显然你也可以用其他方式来做,例如这样:
$rules = ['program' => 'required'];
if (in_array('Music', $request->input('program', [])))
$rules['music_instrument'] = 'required';
$validator = Validator::make($request->all(), $rules);
【讨论】:
我尝试了星号,但它被忽略了。我能够让它与 required_if:program.34,Music,, 一起使用,但为此我必须索引我的列表并跟踪 34,这显然不是一个好主意......我也会尝试这种方法。谢谢。我希望 laravel 的 in_array 能工作,但没有运气 我会接受你的第二个解决方案,因为这就是我的方式:) 谢谢!为了争论,如果其他人想出一个开箱即用的工作配置,我仍然希望看到它......呵呵以上是关于如果值存在于另一个字段数组中,Laravel 验证规则的主要内容,如果未能解决你的问题,请参考以下文章