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

Laravel嵌套验证请求:获取字段实现自定义验证与组合去重

Laravel嵌套数组验证解决方案

一、自定义验证器获取对应项的product_id与product_collection_id

你当前代码中直接通过$this->details.*->product_id传递参数的方式无效,因为在表单请求的rules方法中无法直接动态获取数组索引对应的字段值。正确做法是让自定义验证器通过属性路径自行提取对应字段:

1. 编写ProductAndCollectionValidator规则

namespace App\Rules;

use Illuminate\Contracts\Validation\Rule;

class ProductAndCollectionValidator implements Rule
{
    public function passes($attribute, $value)
    {
        // 从属性名中解析出数组索引,例如"details.0.product_collection_id" -> 索引0
        $segments = explode('.', $attribute);
        $index = $segments[1];
        
        // 获取当前项对应的product_id
        $productId = request()->input("details.$index.product_id");
        // 当前项的product_collection_id(可能为null)
        $collectionId = $value;

        // 此处编写你的核心验证逻辑
        // 示例:若collection_id不为null,校验产品是否属于该集合
        if (!is_null($collectionId)) {
            // 替换为你的实际业务逻辑,比如:
            // $product = \App\Models\Product::find($productId);
            // return $product && $product->product_collection_id == $collectionId;
        }

        // 若collection_id为null,默认验证通过(可根据需求调整)
        return true;
    }

    public function message()
    {
        return '产品与集合的组合无效';
    }
}

2. 更新验证规则配置

在表单请求的rules方法中,只需实例化验证器,无需传递参数:

return [
    // ...其他规则
    'amount' => ['nullable', 'numeric'],
    'currency_id' => ['nullable', 'integer', Rule::in($allowedCurrencyIds)],
    'details' => ['nullable', 'array'], // 先标记为数组类型
    'details.*.product_id' => ['required', 'integer', 'exists:products,id'],
    'details.*.product_collection_id' => [
        'nullable',
        'integer',
        'exists:product_collections,id',
        new ProductAndCollectionValidator(),
    ],
    // ...其他规则
];

二、验证details数组中无重复的product_id+product_collection_id组合

新增一个自定义规则来校验组合唯一性:

1. 编写UniqueProductCollectionPair规则

namespace App\Rules;

use Illuminate\Contracts\Validation\Rule;

class UniqueProductCollectionPair implements Rule
{
    public function passes($attribute, $value)
    {
        $seenPairs = [];

        foreach ($value as $item) {
            // 将product_id和collection_id转为唯一标识字符串,兼容null场景
            $pairKey = json_encode([
                'product_id' => $item['product_id'],
                'product_collection_id' => $item['product_collection_id'] ?? null
            ]);

            if (in_array($pairKey, $seenPairs)) {
                return false; // 发现重复组合
            }

            $seenPairs[] = $pairKey;
        }

        return true;
    }

    public function message()
    {
        return '详情中存在重复的产品与集合组合';
    }
}

2. 绑定到details字段的验证规则

更新details字段的规则,添加该自定义规则:

'details' => ['nullable', 'array', new UniqueProductCollectionPair()],

最终完整验证规则示例

return [
    'amount' => ['nullable', 'numeric'],
    'currency_id' => ['nullable', 'integer', Rule::in($allowedCurrencyIds)],
    'details' => ['nullable', 'array', new UniqueProductCollectionPair()],
    'details.*.product_id' => ['required', 'integer', 'exists:products,id'],
    'details.*.product_collection_id' => [
        'nullable',
        'integer',
        'exists:product_collections,id',
        new ProductAndCollectionValidator(),
    ],
    // ...其他规则
];

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 02:06:30