Laravel Livewire数组场景下自定义日期同年度验证规则实现咨询
实现Laravel数组字段关联自定义验证规则
要实现date_to不超过对应date_from当年年末的验证,不用临时字段,直接通过自定义验证规则关联同索引的数组字段即可,步骤如下:
1. 创建自定义验证规则类
用Artisan命令生成规则文件:
php artisan make:rule EndOfYearOfField
打开生成的app/Rules/EndOfYearOfField.php,替换内容为:
<?php namespace App\Rules; use Illuminate\Contracts\Validation\Rule; use Carbon\Carbon; class EndOfYearOfField implements Rule { protected $targetFieldTemplate; // 接收目标字段的模板(比如positions.*.date_from) public function __construct(string $targetFieldTemplate) { $this->targetFieldTemplate = $targetFieldTemplate; } public function passes($attribute, $value) { // 拆分当前验证字段的结构,提取数组索引 $parts = explode('.', $attribute); // 校验字段格式是否符合positions.[索引].date_to if (count($parts) < 3 || $parts[0] !== 'positions' || $parts[2] !== 'date_to') { return false; } $index = $parts[1]; // 替换目标字段模板中的*为当前索引,拿到对应date_from的字段名 $targetField = str_replace('*', $index, $this->targetFieldTemplate); // 获取对应位置的date_from值 $dateFrom = request()->input($targetField); if (!$dateFrom) { return false; } // 计算date_from所在年份的年末日期 $endOfYear = Carbon::parse($dateFrom)->endOfYear()->format('Y-m-d'); // 验证date_to是否小于等于年末日期 return Carbon::parse($value)->lte($endOfYear); } public function message() { return '结束日期不能超过开始日期所在年份的年末。'; } }
2. 在Livewire组件中使用自定义规则
修改组件的rules()方法,给date_to添加自定义规则:
protected function rules() { return [ 'positions.*.date_from' => 'required|date', 'positions.*.date_to' => [ 'required', 'date', 'after_or_equal:positions.*.date_from', // 传入目标字段模板,规则会自动匹配同索引的date_from new \App\Rules\EndOfYearOfField('positions.*.date_from'), ], ]; }
原理说明
- 规则类通过解析当前验证字段的名称(比如
positions.0.date_to)提取出数组索引0 - 将传入的目标字段模板
positions.*.date_from中的*替换为索引,得到对应位置的positions.0.date_from - 获取该字段的值后计算当年年末,再与当前验证的
date_to对比
这种方式完全基于Laravel的验证系统扩展,不需要临时字段,属于正规的实现方案。
内容的提问来源于stack exchange,提问作者Christian Wagner
相关产品推荐
相关产品推荐

