Laravel 7 : 带有通配符索引的数组验证消息

Laravel 7 : array validation messages with wildcard index

所以我有一组数据(不一定来自 $request)

       $validator = Validator::make($array, [
           '*.client_name' => 'required',
           '*.client_phone' => ['required ', 'regex:/^(0)(5|6|7)[0-9]{8}/'],
       ]);

       $validator->validate();

到目前为止,验证消息显示为

The field 1.client_name is required

我想要类似的东西

Row 1 : The field client_name is required

如果我使用 $validator->setAttributeNames($newAttributeNames); 我会丢失通配符 (*) 中的行号,即使我在新属性名称中设置了通配符。

另请注意,我不想覆盖 laravel 提供的所有规则的消息(这里有 2 个示例,但实际上我有很多规则)

那么知道如何完成这个吗?

我通常使用的一种方法是动态验证;根据您上传的输入,构造 $rules$messages:

$rules = [];
$messages = [];
for($i = 0; $i <= count($array); $i++){
  // Since arrays are 0-based, 0 will be Row 1, etc.
  // If you want index 0 to be Row 0, then just use `$i` below
  $rowNum = $i + 1; 

  $cnKey = "{$i}.client_name";

  $rules[$cnKey] = 'required';
  $messages["{$cnKey}.required"] = "Row {$rowNum}: The field client_name is required";

  $cpKey = "{$i}.client_phone";

  $rules[$cpKey] = ['required', 'regex:/^(0)(5|6|7)[0-9]{8}/'];
  $messages["{$cpKey}.required"] = "Row {$rowNum}: The field client_phone is required";
  $messages["{$cpKey}.regex"] = "Row {$rowNum}: The field client_phone format is invalid";
}

$validator = Validator::make($array, $rules, $messages);
$validator->validate();

这会丢弃通配符,并显式使用 0.client_name0.client_phone 等,并允许您即时构建唯一的验证消息。

到目前为止我能找到的最佳方法是从@Tim Welis 的回答中得到启发,但使用循环代替

$rules = [
    '*.client_name' => 'required',
    '*.client_phone' => ['required ', 'regex:/^(0)(5|6|7)[0-9]{8}/'],
    '*.age' => 'required | numeric | between:0,100',
];

$messages = [];
foreach($array as $rowNum => $row)
{
    foreach($row as $field => $value) {
        $messages["{$rowNum}.".$field.'.required'] = "Row {$rowNum} : The field {$field} is required";
        $messages["{$rowNum}.".$field.'.regex'] = "Row {$rowNum} : The field {$field} format is invalid";
        $messages["{$rowNum}.".$field.'.numeric'] = "Row {$rowNum} : The field {$field} must be numeric";
        $messages["{$rowNum}.".$field.'.between'] = "Row {$rowNum} : The field {$field} value must be between :min - :max";
    }
}

$validator = Validator::make($array, $rules, $messages);
$validator->validate();   

所有属性只写一次规则消息