Laravel嵌套数组请求验证:一个为0时另一个需大于0
解决Laravel嵌套数组的自定义验证问题
核心问题修复
你无法直接通过$request['variable_b']或通配符*获取对应嵌套项的variable_b,是因为自定义规则闭包中的attribute包含了具体的索引(比如nested_array.0.variable_a),可以通过解析这个属性名拿到当前项的索引,再获取对应的variable_b值:
$rules = [ 'nested_array.*.variable_a' => [ 'integer', 'between:0,1', function ($attribute, $value, $fail) use ($request) { // 拆分属性名获取当前嵌套项的索引 $parts = explode('.', $attribute); $index = $parts[1]; // 获取对应索引的variable_b值 $variableB = $request->input("nested_array.$index.variable_b"); if (!$value && !$variableB) { $fail("$attribute 无效,variable_a和variable_b不能同时为0。"); } } ], 'nested_array.*.variable_b' => 'integer|between:0,1', 'nested_array.*.order' => ['required', 'integer'], ];
替代方案:使用验证器后置回调
如果觉得闭包内解析属性名不够直观,可以用Laravel的验证器后置回调,直接遍历嵌套数组进行逻辑判断:
use Illuminate\Support\Facades\Validator; $rules = [ 'nested_array' => ['required', 'array'], 'nested_array.*.variable_a' => 'integer|between:0,1', 'nested_array.*.variable_b' => 'integer|between:0,1', 'nested_array.*.order' => 'required|integer', ]; $validator = Validator::make($request->all(), $rules); $validator->after(function ($validator) use ($request) { foreach ($request->input('nested_array', []) as $index => $item) { // 确保两个字段都存在且同时为0时触发错误 if (isset($item['variable_a'], $item['variable_b']) && !$item['variable_a'] && !$item['variable_b']) { $validator->errors()->add("nested_array.$index.variable_a", 'variable_a和variable_b不能同时为0。'); } } }); // 执行验证 if ($validator->fails()) { // 处理验证失败逻辑,比如返回错误信息 return redirect()->back()->withErrors($validator); }
进阶方案:自定义验证规则类
如果后续验证逻辑会更复杂,推荐封装成自定义规则类,提升代码可维护性:
- 生成规则类:
php artisan make:rule AtLeastOneOfAB
- 实现规则逻辑:
namespace App\Rules; use Illuminate\Contracts\Validation\Rule; class AtLeastOneOfAB implements Rule { protected $otherFieldValue; public function __construct($otherFieldValue) { $this->otherFieldValue = $otherFieldValue; } public function passes($attribute, $value) { // 只要其中一个值不为0就通过验证 return $value || $this->otherFieldValue; } public function message() { return 'variable_a和variable_b不能同时为0。'; } }
- 在验证规则中使用:
use App\Rules\AtLeastOneOfAB; $rules = []; foreach ($request->input('nested_array', []) as $index => $item) { $rules["nested_array.$index.variable_a"] = [ 'integer', 'between:0,1', new AtLeastOneOfAB($item['variable_b'] ?? 0) ]; } // 补充其他固定规则 $rules['nested_array.*.variable_b'] = 'integer|between:0,1'; $rules['nested_array.*.order'] = 'required|integer'; $validator = Validator::make($request->all(), $rules);
内容的提问来源于stack exchange,提问作者Mr. Kenneth
相关产品推荐
相关产品推荐

