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

Laravel 9多场景API验证实现求助(需自定义规则示例)

解决方案:Laravel 9 多场景API验证实现

一、核心实现方案

针对你的需求,我们采用FormRequest类(Laravel复杂验证推荐方案)结合自定义验证规则,实现动态场景控制、字段格式校验及依赖验证逻辑。


二、场景1:依source动态控制company_number与gst_number

实现步骤

  1. 创建CompanyRequest.php(存放于app/Http/Requests目录)
  2. 在rules()方法中根据source值动态生成对应验证规则
  3. 利用required_without、prohibited等规则匹配场景逻辑

代码示例

<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rule;

class CompanyRequest extends FormRequest
{
    // 开启验证失败即终止,提升效率
    protected $stopOnFirstFailure = true;

    public function authorize()
    {
        return true; // 可根据实际权限逻辑调整
    }

    public function rules()
    {
        $baseRules = [
            'company_name' => ['required', 'string'],
            'country' => ['required', 'string', 'regex:/^[A-Z]{2}$/', Rule::exists('countries', 'iso_code')],
            'source' => ['required', 'numeric', Rule::exists('sources', 'id')],
        ];

        // 根据source值匹配对应验证规则
        switch ($this->source) {
            case 1:
                // source=1时,两个字段均非必填
                $baseRules['company_number'] = ['nullable', 'string'];
                $baseRules['gst_number'] = ['nullable', 'string', 'regex:/^([0-9]{2}[a-zA-Z]{5}[0-9]{4}[a-zA-Z]{1}[0-9]{1}Z{1}[0-9A-Za-z]{1})$/'];
                break;
            case 2:
                // source=2时,必填其一且不可同时存在
                $baseRules['company_number'] = ['required_without:gst_number', 'string', 'prohibited_if:gst_number,!null'];
                $baseRules['gst_number'] = ['required_without:company_number', 'string', 'prohibited_if:company_number,!null', 'regex:/^([0-9]{2}[a-zA-Z]{5}[0-9]{4}[a-zA-Z]{1}[0-9]{1}Z{1}[0-9A-Za-z]{1})$/'];
                break;
            default:
                // source为其他值时,仅允许company_number,禁止gst_number
                $baseRules['company_number'] = ['required', 'string'];
                $baseRules['gst_number'] = ['prohibited'];
                break;
        }

        // 合并country-state验证规则
        $baseRules = array_merge($baseRules, $this->getCountryStateRules());

        return $baseRules;
    }

    // 自定义错误提示(可选)
    public function messages()
    {
        return [
            'gst_number.prohibited' => '当前source值不允许提交gst_number',
            'state.prohibited' => '当前国家无需填写state字段',
            'state.belongs_to_country' => 'state不属于当前国家的有效列表',
        ];
    }
}

三、场景2:Country-State映射验证

实现步骤

  1. 创建自定义验证规则BelongsToCountry.php(存放于app/Rules目录)
  2. 在FormRequest中调用该规则,结合prohibited、required_if完成场景校验

1. 自定义验证规则BelongsToCountry.php

<?php

namespace App\Rules;

use Illuminate\Contracts\Validation\Rule;

class BelongsToCountry implements Rule
{
    protected $country;

    public function __construct($country)
    {
        $this->country = $country;
    }

    public function passes($attribute, $value)
    {
        // 替换为你已有的国家-state映射列表
        $countryStates = [
            'X' => ['CA', 'NY'],
            'Y' => ['TX', 'FL'],
            'Z' => ['ON', 'QC'],
        ];

        return isset($countryStates[$this->country]) && in_array($value, $countryStates[$this->country]);
    }

    public function message()
    {
        return 'state不属于当前国家的有效列表';
    }
}

2. 在FormRequest中添加Country-State规则

在CompanyRequest.php中新增方法:

protected function getCountryStateRules()
{
    $rules = [];

    // 强制校验state格式:无论是否必填,空值或格式错误直接报错
    $rules['state'] = [
        'string',
        'regex:/^[A-Z]{2}$/',
        // 非X/Y/Z国家禁止提交state
        Rule::prohibitedIf(!in_array($this->country, ['X', 'Y', 'Z'])),
        // X/Y/Z国家必须提交state
        Rule::requiredIf(in_array($this->country, ['X', 'Y', 'Z'])),
        // 校验state是否属于对应国家
        new \App\Rules\BelongsToCountry($this->country),
    ];

    return $rules;
}

四、多余字段处理

若需对多余字段触发验证错误,可在CompanyRequest.php中添加以下逻辑:

protected function prepareForValidation()
{
    $allowedFields = ['company_name', 'company_number', 'gst_number', 'country', 'state', 'source'];
    $extraFields = array_diff(array_keys($this->all()), $allowedFields);

    if (!empty($extraFields)) {
        throw new \Illuminate\Validation\ValidationException(
            \Illuminate\Validation\Validator::make([], [])->errors()->add('extra_fields', '不允许提交以下字段: ' . implode(',', $extraFields))
        );
    }
}

五、控制器中使用

在API控制器中直接注入CompanyRequest即可自动触发验证:

public function store(CompanyRequest $request)
{
    // 验证通过后获取合规数据
    $validatedData = $request->validated();
    // 后续业务逻辑处理
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 16:20:30