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

Laravel验证嵌套JSON时如何向自定义规则传入当前索引的对象

解决方案

你可以通过解析当前验证属性的路径获取数组索引,再拿到同索引下的完整对象,以下是两种常用实现方式:


方案1:修改现有自定义规则类(推荐,适合复用逻辑)

直接修改你的SeatIsAvailable规则类,在passes方法中解析属性路径获取当前索引,再从请求中获取对应完整座位数据:

<?php

namespace App\Rules;

use Illuminate\Contracts\Validation\Rule;

class SeatIsAvailable implements Rule
{
    public function passes($attribute, $value)
    {
        // 拆分属性路径获取当前数组索引,对应seats.*.seat_no里的*位置
        $index = explode('.', $attribute)[1];
        // 获取当前索引对应的完整座位对象
        $seat = request()->input("seats.{$index}");

        $scheduleId = $seat['schedule_id'] ?? null;
        $date = $seat['date'] ?? null;

        // 基础参数非空判断(调整规则顺序后可省略)
        if (!$scheduleId || !$date) {
            return false;
        }

        // 这里写你的实际校验逻辑,比如查询座位是否在指定排班、日期下可用
        return !\App\Models\Seat::where('schedule_id', $scheduleId)
            ->where('date', $date)
            ->where('seat_no', $value)
            ->exists();
    }

    public function message()
    {
        return '该座位在指定日期和排班下已被占用';
    }
}

这个方案不需要修改你现有CheckoutRequest的调用逻辑,仅建议调整规则顺序,保证schedule_id和date的基础校验在seat_no之前,避免参数缺失问题:

public function rules()
{
    return [
        "company" => "required",
        "seats" => "required|array",
        "seats.*.schedule_id" => "required|numeric",
        "seats.*.date" => "required|date",
        "seats.*.seat_no" => ['required', new SeatIsAvailable()],
    ];
}

方案2:使用闭包验证(适合逻辑无需复用的场景)

如果校验逻辑不需要在其他地方复用,可以直接在表单请求规则中用闭包实现,无需额外创建规则类:

public function rules()
{
    return [
        "company" => "required",
        "seats" => "required|array",
        "seats.*.schedule_id" => "required|numeric",
        "seats.*.date" => "required|date",
        "seats.*.seat_no" => [
            'required',
            function ($attribute, $value, $fail) {
                $index = explode('.', $attribute)[1];
                $seat = $this->input("seats.{$index}");

                if (\App\Models\Seat::where('schedule_id', $seat['schedule_id'])
                    ->where('date', $seat['date'])
                    ->where('seat_no', $value)
                    ->exists()) {
                    $fail("座位{$value}在指定日期已被占用");
                }
            }
        ],
    ];
}

内容的提问来源于stack exchange,提问作者user3718908x100

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 13:15:05