You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 23:01:29