如何在Laravel中实现对比数组中两个值的自定义验证器?
我来帮你搞定这个自定义验证器的问题!你要实现的是对请求数组中每个对象的outcome_id对应Outcome模型的odds值,和当前项输入的odds做匹配验证,对吧?下面是完整的实现方案:
实现数组对象的自定义验证器:
oddIs规则 1. 补全自定义验证器核心逻辑
你的代码片段还差关键的输入值获取逻辑,这里我们通过属性名替换来精准拿到同数组项的odds值,同时处理模型查询空值的异常情况:
Validator::extend('oddIs', function($attribute, $value, $parameters, $validator) { // 把当前验证的属性(比如"0.outcome_id")转换成对应项的odds属性名"0.odds" $oddsAttribute = str_replace('outcome_id', 'odds', $attribute); // 从请求数据中取出对应的输入odds值 $inputOdds = $validator->getData()[$oddsAttribute] ?? null; // 查询对应的Outcome模型,处理找不到记录的情况 $outcome = Outcome::find($value); if (!$outcome) { // 若outcome不存在,直接返回验证失败(可根据需求调整逻辑) return false; } // 对比模型存储的odds和输入的odds值 return $outcome->odds == $inputOdds; });
2. 验证规则的正确写法
你原来的规则写法基本没问题,不过可以简化掉参数传递(我们通过属性名替换已经能拿到对应值):
$this->validate($request, [ '*.odds' => 'required', '*.outcome_id' => 'required|oddIs' ]);
3. (可选)添加友好的自定义错误提示
如果需要更清晰的错误反馈,可以给这个规则添加替换器:
Validator::replacer('oddIs', function($message, $attribute, $parameters, $validator) { $oddsAttribute = str_replace('outcome_id', 'odds', $attribute); $inputOdds = $validator->getData()[$oddsAttribute] ?? '未知值'; $outcome = Outcome::find($validator->getData()[$attribute]); $modelOdds = $outcome ? $outcome->odds : '不存在的记录'; return "输入的赔率「{$inputOdds}」与Outcome记录的赔率「{$modelOdds}」不匹配"; });
关键逻辑说明
- 属性名替换:利用数组项属性名的关联性(
*.outcome_id和*.odds属于同一项),直接替换属性名就能拿到对应值,避免了参数传递可能带来的索引匹配问题。 - 空值防护:查询
Outcome时必须判断是否存在,否则会触发「Trying to get property 'odds' of non-object」的致命错误。
内容的提问来源于stack exchange,提问作者Adnan Haque
相关产品推荐
相关产品推荐

