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

Laravel Maatwebsite Excel导入:基于invite_type的字段条件必填配置

Laravel Maatwebsite Excel 导入条件验证实现

我正在使用Laravel的Maatwebsite Excel包进行数据导入,导入类ClientsImport实现了ToModel、WithHeadingRow、WithValidation、SkipsEmptyRows接口。Excel文件包含Invite Type、email、telephone_number等列,由于使用了WithHeadingRow,导入时通过表头访问列值。需要实现以下条件验证规则:

  • 当invite_type为"email"时,email字段必填
  • 当invite_type为"sms"时,telephone_number字段必填
  • 当invite_type为"both"时,email和telephone_number字段均必填

以下是我当前的导入类代码:

<?php

namespace App\Imports;

use App\Models\InviteUser;
use Illuminate\Validation\Rule;
use Illuminate\Validation\Rules\RequiredIf;
use Maatwebsite\Excel\Concerns\SkipsEmptyRows;
use Maatwebsite\Excel\Concerns\ToModel;
use Maatwebsite\Excel\Concerns\WithHeadingRow;
use Maatwebsite\Excel\Concerns\WithValidation;

class ClientsImport implements ToModel, WithHeadingRow, WithValidation, SkipsEmptyRows
{
    public function model(array $row)
    {
        dd($row);
    }

    public function rules(): array
    {
        return [
            'first_name' => ['required', 'string', 'max:125'],
            'last_name' => ['required', 'string', 'max:125'],
            'email' => [
                'required',
                'string',
                'email',
                'distinct',
                [new RequiredIf(empty($this->invite_type) || in_array($this->invite_type,['email','both'])), 'string', 'email','distinct'],
            ],
            'telephone_number' => [
                'required',
                'string',
                [new RequiredIf(empty($this->invite_type) || in_array($this->invite_type,['sms','both'])), 'string','distinct'],
            ],
            'invite_type' => ['required', 'string', 'in:email,sms,both'],
        ];
    }

    public function customValidationMessages()
    {
        return [
            'invite_type.in' => 'The selected invite_type is invalid. Allowed types are following (email, sms, both).',
           'telephone_number.required' => 'The telephone number field is required when invite type is both or sms.',
            'email.required' => 'The email field is required when invite_type is both or email.',
        ];
    }

    public function customValidationAttributes()
    {
        return [
            'invite_type' => 'invite type',
            'telephone_number' => 'Telephone number',
        ];
    }
}

当前代码存在的问题

  1. 错误引用$this->invite_type:类中未定义该属性,无法获取当前行的invite_type值
  2. 重复验证规则:email和telephone_number中重复定义了string、email、distinct等规则
  3. 固定required规则:无论invite_type是什么,都强制要求email和telephone_number必填,不符合条件验证需求

修正后的代码

<?php

namespace App\Imports;

use App\Models\InviteUser;
use Illuminate\Validation\Rule;
use Maatwebsite\Excel\Concerns\SkipsEmptyRows;
use Maatwebsite\Excel\Concerns\ToModel;
use Maatwebsite\Excel\Concerns\WithHeadingRow;
use Maatwebsite\Excel\Concerns\WithValidation;

class ClientsImport implements ToModel, WithHeadingRow, WithValidation, SkipsEmptyRows
{
    public function model(array $row)
    {
        dd($row);
    }

    public function rules(): array
    {
        return [
            'first_name' => ['required', 'string', 'max:125'],
            'last_name' => ['required', 'string', 'max:125'],
            'email' => [
                'string',
                'email',
                'distinct',
                Rule::requiredIf(function ($input) {
                    return in_array($input['invite_type'], ['email', 'both']);
                }),
            ],
            'telephone_number' => [
                'string',
                'distinct',
                Rule::requiredIf(function ($input) {
                    return in_array($input['invite_type'], ['sms', 'both']);
                }),
            ],
            'invite_type' => ['required', 'string', 'in:email,sms,both'],
        ];
    }

    public function customValidationMessages()
    {
        return [
            'invite_type.in' => '所选邀请类型无效,允许的类型为:email、sms、both',
            'telephone_number.required' => '当邀请类型为both或sms时,电话号码为必填项',
            'email.required' => '当邀请类型为both或email时,邮箱为必填项',
        ];
    }

    public function customValidationAttributes()
    {
        return [
            'invite_type' => '邀请类型',
            'telephone_number' => '电话号码',
        ];
    }
}

修正说明

  1. 使用Rule::requiredIf()闭包:通过闭包获取当前验证的输入数据,根据invite_type的值动态判断字段是否必填
  2. 移除固定required规则:仅保留条件必填逻辑,匹配需求
  3. 清理重复规则:删除重复的验证规则,保持代码简洁
  4. 优化提示信息:将英文提示改为中文,更贴合使用场景

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 22:39:57