Laravel 9:如何在自定义验证规则中调用已有验证规则?
在Laravel 9中实现UsernameOrEmail自定义验证规则
下面提供两种合规的实现方案,替代你原本调用受保护方法validateAttribute的思路:
方案一:直接调用规则自身的验证逻辑
自定义规则类(如Username)和Laravel内置的Email规则都具备独立的验证能力,无需依赖外部Validator实例,实现更轻量化:
基于Rule接口的实现
use Illuminate\Contracts\Validation\Rule; use Illuminate\Validation\Rules\Email; class UsernameOrEmail implements Rule { /** * 验证字段是否有效 * * @param string $attribute * @param mixed $value * @return bool */ public function passes($attribute, $value) { // 验证邮箱格式 $emailValidation = (new Email())->passes($attribute, $value); // 验证用户名格式 $usernameValidation = (new Username())->passes($attribute, $value); return $emailValidation || $usernameValidation; } /** * 返回错误提示信息 * * @return string */ public function message() { return 'The :attribute is not a valid username or email.'; } }
可调用规则的实现(Laravel 9推荐方式)
use Illuminate\Validation\Rules\Email; class UsernameOrEmail { /** * 执行验证 * * @param string $attribute * @param mixed $value * @param \Closure $fail * @return void */ public function __invoke($attribute, $value, $fail) { $isValidEmail = (new Email())->passes($attribute, $value); $isValidUsername = (new Username())->passes($attribute, $value); if (!$isValidEmail && !$isValidUsername) { $fail('The :attribute is not a valid username or email.'); } } }
方案二:利用临时Validator实例验证
如果需要复用现有Validator的配置上下文,可以创建临时Validator实例来测试字段值:
use Illuminate\Support\Facades\Validator; class UsernameOrEmail { protected $validator; public function setValidator($validator) { $this->validator = $validator; return $this; } public function __invoke($attribute, $value, $fail) { // 验证邮箱 $emailCheck = Validator::make( [$attribute => $value], [$attribute => 'email'] )->passes(); // 验证用户名 $usernameCheck = Validator::make( [$attribute => $value], [$attribute => new Username()] )->passes(); if (!$emailCheck && !$usernameCheck) { $fail('The :attribute is not a valid username or email.'); } } }
关键说明
Laravel的validateAttribute是受保护方法,无法在自定义规则类外部调用,上述两种方案都是官方推荐的合规替代方式,能准确复用内置规则和自定义规则的验证逻辑。
内容的提问来源于stack exchange,提问作者user4181107
相关产品推荐
相关产品推荐

