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

Laravel递归验证API请求属性失败的问题及修复

解决动态查询构建器POST请求递归验证失效问题

1. 排查自定义递归规则的核心逻辑

你的问题大概率是自定义RecursiveConditionRule没有正确区分单个条件和条件组的结构,或者递归验证时没有正确传递验证上下文。以Laravel为例,自定义规则的passes方法需要明确判断当前节点类型:

class RecursiveConditionRule implements Rule
{
    private $message;

    public function passes($attribute, $value)
    {
        // 验证单个条件的情况
        if (isset($value['type_slug'])) {
            $validator = Validator::make($value, [
                'type_slug' => 'required|string',
                'logical_operator' => 'required|in:eq,neq,gt,lt',
                'value' => 'required',
                // 补充单个条件的其他必填字段规则
            ]);
            if ($validator->fails()) {
                $this->message = $validator->errors()->first();
                return false;
            }
            return true;
        }

        // 验证条件组的情况
        if (isset($value['children'])) {
            $validator = Validator::make($value, [
                'logical_operator' => 'required|in:and,or',
                'children' => 'required|array|min:1',
            ]);
            if ($validator->fails()) {
                $this->message = $validator->errors()->first();
                return false;
            }
            // 递归验证子条件列表
            foreach ($value['children'] as $index => $child) {
                $childAttr = "{$attribute}.children.{$index}";
                if (!$this->passes($childAttr, $child)) {
                    return false;
                }
            }
            return true;
        }

        // 不符合任何合法结构的情况
        $this->message = "Invalid condition structure at {$attribute}";
        return false;
    }

    public function message()
    {
        return $this->message;
    }
}

2. 修正主验证规则的写法

不要给conditions.*单独加字段级必填规则,而是直接将自定义规则应用到整个conditions数组:

public function rules()
{
    return [
        'conditions' => ['required', 'array', new RecursiveConditionRule],
        // 其他顶级请求字段的验证规则
    ];
}

如果给conditions.*.type_slug这类字段强制加必填规则,会要求所有元素都必须是单个条件,而忽略了条件组的存在,这就是你收到必填错误的核心原因。

3. 对齐请求JSON结构与规则预期

确保你的请求JSON结构和规则判断逻辑一致,比如条件组用children字段嵌套子条件,而非重复使用conditions字段:

{
    "conditions": [
        {
            "logical_operator": "and",
            "children": [
                {
                    "type_slug": "user_age",
                    "logical_operator": "gt",
                    "value": 18
                },
                {
                    "logical_operator": "or",
                    "children": [
                        {
                            "type_slug": "user_role",
                            "logical_operator": "eq",
                            "value": "admin"
                        }
                    ]
                }
            ]
        }
    ]
}

4. 调试验证过程

在自定义规则的passes方法中添加日志,输出当前验证的$attribute和$value,确认递归时是否正确遍历到所有嵌套节点:

Log::info("Validating node: {$attribute}", $value);

通过日志可以快速定位是某个节点的结构不符合预期,还是递归逻辑没有触发。

内容的提问来源于stack exchange,提问作者Avnee.Angel

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 06:42:53