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', ]; } }
当前代码存在的问题
- 错误引用
$this->invite_type:类中未定义该属性,无法获取当前行的invite_type值 - 重复验证规则:
email和telephone_number中重复定义了string、email、distinct等规则 - 固定
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' => '电话号码', ]; } }
修正说明
- 使用
Rule::requiredIf()闭包:通过闭包获取当前验证的输入数据,根据invite_type的值动态判断字段是否必填 - 移除固定
required规则:仅保留条件必填逻辑,匹配需求 - 清理重复规则:删除重复的验证规则,保持代码简洁
- 优化提示信息:将英文提示改为中文,更贴合使用场景
内容的提问来源于stack exchange,提问作者Noman Zahid
相关产品推荐
相关产品推荐

