验证
简介
验证规则可添加到任意 字段。
在 Laravel 中,验证规则通常定义为数组(如 ['required', 'max:255'])或组合字符串(如 required|max:255)。若你仅在后端使用简单的 form request,这样即可。但 Filament 还能为用户提供前端验证,让他们在发起任何后端请求之前就能修正错误。
Filament 包含许多 专用验证方法,你也可以使用任意 其他 Laravel 验证规则,包括 自定义验证规则。


WARNING
部分默认 Laravel 验证规则依赖正确的属性名,通过 rule()/rules() 传入时可能无效。尽可能使用专用验证方法。
可用规则
有效 URL
根据 PHP 的 dns_get_record() 函数,该字段必须具有有效的 A 或 AAAA 记录。参见 Laravel 文档。
Field::make('name')->activeUrl()之后(日期)
字段值必须是给定日期之后的值。参见 Laravel 文档。
Field::make('start_date')->after('tomorrow')或者,你可以传入另一个字段名以进行比较:
Field::make('start_date')
Field::make('end_date')->after('start_date')之后或等于(日期)
字段值必须是给定日期之后或等于该日期的日期。参见 Laravel 文档。
Field::make('start_date')->afterOrEqual('tomorrow')或者,你可以传入另一个字段名以进行比较:
Field::make('start_date')
Field::make('end_date')->afterOrEqual('start_date')字母
字段必须完全由字母字符组成。参见 Laravel 文档。
Field::make('name')->alpha()字母、数字、破折号与下划线
字段可以包含字母数字字符,以及破折号与下划线。参见 Laravel 文档。
Field::make('name')->alphaDash()字母数字
字段必须完全由字母数字字符组成。参见 Laravel 文档。
Field::make('name')->alphaNum()ASCII
字段必须完全由 7 位 ASCII 字符组成。参见 Laravel 文档。
Field::make('name')->ascii()之前(日期)
字段值必须是给定日期之前的日期。参见 Laravel 文档。
Field::make('start_date')->before('first day of next month')或者,你可以传入另一个字段名以进行比较:
Field::make('start_date')->before('end_date')
Field::make('end_date')之前或等于(日期)
字段值必须是给定日期之前或等于该日期的日期。参见 Laravel 文档。
Field::make('start_date')->beforeOrEqual('end of this month')或者,你可以传入另一个字段名以进行比较:
Field::make('start_date')->beforeOrEqual('end_date')
Field::make('end_date')确认
字段必须有一个匹配的 {field}_confirmation 字段。参见 Laravel 文档。
Field::make('password')->confirmed()
Field::make('password_confirmation')不同
字段值必须与另一个字段不同。参见 Laravel 文档。
Field::make('backup_email')->different('email')不以…开头
字段不得以给定值之一开头。参见 Laravel 文档。
Field::make('name')->doesntStartWith(['admin'])不以…结尾
字段不得以给定值之一结尾。参见 Laravel 文档。
Field::make('name')->doesntEndWith(['admin'])以…结尾
字段必须以给定值之一结尾。参见 Laravel 文档。
Field::make('name')->endsWith(['bot'])枚举
字段必须包含有效的枚举值。参见 Laravel 文档。
Field::make('status')->enum(MyStatus::class)存在
字段值必须在数据库中存在。参见 Laravel 文档。
Field::make('invitation')->exists()默认情况下,若表单 已注册模型,将在该模型中搜索。你可以指定自定义表名或模型进行搜索:
use App\Models\Invitation;
Field::make('invitation')->exists(table: Invitation::class)默认情况下,将使用字段名作为搜索列。你可以指定自定义列进行搜索:
Field::make('invitation')->exists(column: 'id')你可以通过向 modifyRuleUsing 参数传入 闭包 进一步自定义该规则:
use Illuminate\Validation\Rules\Exists;
Field::make('invitation')
->exists(modifyRuleUsing: function (Exists $rule) {
return $rule->where('is_active', 1);
})Laravel 的 exists 验证规则默认不使用 Eloquent 模型查询数据库,因此不会应用模型上定义的任何全局作用域(包括软删除)。因此,即使存在具有相同值的软删除记录,验证也会通过。
由于未应用全局作用域,Filament 的多租户功能默认也不会将查询限定为当前租户。
为此,你应改用 scopedExists() 方法,它用基于模型查询数据库的实现替换 Laravel 的 exists,并应用模型上定义的任何全局作用域(包括软删除与多租户):
use Filament\Forms\Components\TextInput;
TextInput::make('email')
->scopedExists()若希望修改用于检查存在性的 Eloquent 查询(包括移除全局作用域),可以向 modifyQueryUsing 参数传入函数:
use Filament\Forms\Components\TextInput;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\SoftDeletingScope;
TextInput::make('email')
->scopedExists(modifyQueryUsing: function (Builder $query) {
return $query->withoutGlobalScope(SoftDeletingScope::class);
})已填写
字段在存在时不得为空。参见 Laravel 文档。
Field::make('name')->filled()大于
字段值必须大于另一个字段。参见 Laravel 文档。
Field::make('newNumber')->gt('oldNumber')大于或等于
字段值必须大于或等于另一个字段。参见 Laravel 文档。
Field::make('newNumber')->gte('oldNumber')十六进制颜色
字段值必须是有效的十六进制格式颜色。参见 Laravel 文档。
Field::make('color')->hexColor()包含于
字段必须包含在给定的值列表中。参见 Laravel 文档。
Field::make('status')->in(['pending', 'completed'])IP 地址
字段必须是 IP 地址。参见 Laravel 文档。
Field::make('ip_address')->ip()
Field::make('ip_address')->ipv4()
Field::make('ip_address')->ipv6()JSON
字段必须是有效的 JSON 字符串。参见 Laravel 文档。
Field::make('ip_address')->json()小于
字段值必须小于另一个字段。参见 Laravel 文档。
Field::make('newNumber')->lt('oldNumber')小于或等于
字段值必须小于或等于另一个字段。参见 Laravel 文档。
Field::make('newNumber')->lte('oldNumber')MAC 地址
字段必须是 MAC 地址。参见 Laravel 文档。
Field::make('mac_address')->macAddress()倍数
字段必须是某值的倍数。参见 Laravel 文档。
Field::make('number')->multipleOf(2)不包含于
字段不得包含在给定的值列表中。参见 Laravel 文档。
Field::make('status')->notIn(['cancelled', 'rejected'])不匹配正则
字段不得匹配给定的正则表达式。参见 Laravel 文档。
Field::make('email')->notRegex('/^.+$/i')可为空
字段值可以为空。若未出现 required 规则,默认会应用此规则。参见 Laravel 文档。
Field::make('name')->nullable()禁止
字段值必须为空。参见 Laravel 文档。
Field::make('name')->prohibited()在…时禁止
仅当 其他指定字段具有给定值之一时,该字段必须为空。参见 Laravel 文档。
Field::make('name')->prohibitedIf('field', 'value')除非…否则禁止
除非 其他指定字段具有给定值之一,否则该字段必须为空。参见 Laravel 文档。
Field::make('name')->prohibitedUnless('field', 'value')禁止其他字段
若该字段不为空,则所有其他指定字段必须为空。参见 Laravel 文档。
Field::make('name')->prohibits('field')
Field::make('name')->prohibits(['field', 'another_field'])必填
字段值不得为空。参见 Laravel 文档。
Field::make('name')->required()将字段标记为必填
默认情况下,必填字段会在其标签旁显示星号 *。在所有字段都必填的表单上,或者更适合为可选字段添加 提示 时,你可能希望隐藏该星号:
use Filament\Forms\Components\TextInput;
TextInput::make('name')
->required() // Adds validation to ensure the field is required
->markAsRequired(false) // Removes the asterisk若字段未使用 required(),但仍希望显示星号 *,也可以使用 markAsRequired():
use Filament\Forms\Components\TextInput;
TextInput::make('name')
->markAsRequired()在…时必填
仅当 其他指定字段具有给定值之一时,该字段值不得为空。参见 Laravel 文档。
Field::make('name')->requiredIf('field', 'value')在…被接受时必填
仅当 其他指定字段等于 "yes"、"on"、1、"1"、true 或 "true" 时,该字段值不得为空。参见 Laravel 文档。
Field::make('name')->requiredIfAccepted('field')除非…否则必填
除非 其他指定字段具有给定值之一,否则该字段值不得为空。参见 Laravel 文档。
Field::make('name')->requiredUnless('field', 'value')与…同时必填
仅当 其他指定字段中任一不为空时,该字段值不得为空。参见 Laravel 文档。
Field::make('name')->requiredWith('field,another_field')与全部…同时必填
仅当 其他指定字段全部不为空时,该字段值不得为空。参见 Laravel 文档。
Field::make('name')->requiredWithAll('field,another_field')在缺少…时必填
仅当 其他指定字段中任一无值时,该字段值不得为空。参见 Laravel 文档。
Field::make('name')->requiredWithout('field,another_field')在全部缺少…时必填
仅当 其他指定字段全部为空时,该字段值不得为空。参见 Laravel 文档。
Field::make('name')->requiredWithoutAll('field,another_field')正则
字段必须匹配给定的正则表达式。参见 Laravel 文档。
Field::make('email')->regex('/^.+@.+$/i')相同
字段值必须与另一个字段相同。参见 Laravel 文档。
Field::make('password')->same('passwordConfirmation')以…开头
字段必须以给定值之一开头。参见 Laravel 文档。
Field::make('name')->startsWith(['a'])字符串
字段必须是字符串。参见 Laravel 文档。
Field::make('name')->string()唯一
字段值不得在数据库中已存在。参见 Laravel 文档。
Field::make('email')->unique()若你的 Filament 表单已关联 Eloquent 模型(例如在 面板资源 中),Filament 会使用该模型。你也可以指定自定义表名或模型进行搜索:
use App\Models\User;
Field::make('email')->unique(table: User::class)默认情况下,将使用字段名作为搜索列。你可以指定自定义列进行搜索:
Field::make('email')->unique(column: 'email_address')通常,你希望在唯一性验证期间忽略某个给定模型。例如,考虑一个包含用户姓名、电子邮件地址与位置的「更新个人资料」表单。你可能想验证电子邮件地址是否唯一。然而,若用户只更改了姓名字段而未更改电子邮件字段,你不希望因该用户已是该电子邮件地址的所有者而抛出验证错误。若你的 Filament 表单已关联 Eloquent 模型(例如在 面板资源 中),Filament 会忽略它。
若要阻止 Filament 忽略当前 Eloquent 记录,可以向 ignoreRecord 参数传入 false:
Field::make('email')->unique(ignoreRecord: false)或者,要忽略你选择的 Eloquent 记录,可以将其传给 ignorable 参数:
Field::make('email')->unique(ignorable: $ignoredUser)你可以通过向 modifyRuleUsing 参数传入 闭包 进一步自定义该规则:
use Illuminate\Validation\Rules\Unique;
Field::make('email')
->unique(modifyRuleUsing: function (Unique $rule) {
return $rule->where('is_active', 1);
})Laravel 的 unique 验证规则默认不使用 Eloquent 模型查询数据库,因此不会应用模型上定义的任何全局作用域(包括软删除)。因此,即使存在具有相同值的软删除记录,验证也会失败。
由于未应用全局作用域,Filament 的多租户功能默认也不会将查询限定为当前租户。
为此,你应改用 scopedUnique() 方法,它用基于模型查询数据库的实现替换 Laravel 的 unique,并应用模型上定义的任何全局作用域(包括软删除与多租户):
use Filament\Forms\Components\TextInput;
TextInput::make('email')
->scopedUnique()若希望修改用于检查唯一性的 Eloquent 查询(包括移除全局作用域),可以向 modifyQueryUsing 参数传入函数:
use Filament\Forms\Components\TextInput;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\SoftDeletingScope;
TextInput::make('email')
->scopedUnique(modifyQueryUsing: function (Builder $query) {
return $query->withoutGlobalScope(SoftDeletingScope::class);
})ULID
被验证的字段必须是有效的 Universally Unique Lexicographically Sortable Identifier(ULID)。参见 Laravel 文档。
Field::make('identifier')->ulid()UUID
字段必须是有效的 RFC 4122(版本 1、3、4 或 5)通用唯一标识符(UUID)。参见 Laravel 文档。
Field::make('identifier')->uuid()其他规则
你可以使用 rules() 方法为任意字段添加其他验证规则:
TextInput::make('slug')->rules(['alpha_dash'])完整的验证规则列表可在 Laravel 文档 中找到。
自定义规则
你可以像在 Laravel 中一样使用任意自定义验证规则:
TextInput::make('slug')->rules([new Uppercase()])你也可以使用 闭包规则:
use Closure;
TextInput::make('slug')->rules([
fn (): Closure => function (string $attribute, $value, Closure $fail) {
if ($value === 'foo') {
$fail('The :attribute is invalid.');
}
},
])use Filament\Schemas\Components\Utilities\Get;
TextInput::make('slug')->rules([
fn (Get $get): Closure => function (string $attribute, $value, Closure $fail) use ($get) {
if ($get('other_field') === 'foo' && $value !== 'bar') {
$fail("The {$attribute} is invalid.");
}
},
])自定义验证属性
字段验证失败时,会在错误消息中使用其标签。要自定义字段错误消息中使用的标签,请使用 validationAttribute() 方法:
use Filament\Forms\Components\TextInput;
TextInput::make('name')
->validationAttribute('full name')TIP
除了接受静态值,validationAttribute() 方法也接受函数以动态计算该值。你可以将各种工具(utilities)作为参数注入到函数中。
验证消息
默认使用 Laravel 的验证错误消息。要自定义错误消息,请使用 validationMessages() 方法:
use Filament\Forms\Components\TextInput;
TextInput::make('email')
->unique(// ...)
->validationMessages([
'unique' => 'The :attribute has already been registered.',
])TIP
除了接受静态值数组,validationMessages() 方法也为每条消息接受函数。你可以将各种工具(utilities)作为参数注入到函数中。
允许验证消息中使用 HTML
默认情况下,验证消息以纯文本渲染以防止 XSS 攻击。但你可能需要在验证消息中渲染 HTML,例如显示列表或链接时。要为验证消息启用 HTML 渲染,请使用 allowHtmlValidationMessages() 方法:
use Filament\Forms\Components\TextInput;
TextInput::make('password')
->required()
->rules([
new CustomRule(), // Custom rule that returns a validation message that contains HTML
])
->allowHtmlValidationMessages()DANGER
启用此选项会取消对该字段验证消息的转义。请确保每条消息(包括来自自定义规则或翻译的消息)均可安全渲染。不可信内容可能导致 XSS。
在字段未保存时禁用验证
当字段 未保存 时,仍会进行验证。要为未保存的字段禁用验证,请使用 validatedWhenNotDehydrated() 方法:
use Filament\Forms\Components\TextInput;
TextInput::make('name')
->required()
->saved(false)
->validatedWhenNotDehydrated(false)TIP
除了接受静态值,validatedWhenNotDehydrated() 方法也接受函数以动态计算该值。你可以将各种工具(utilities)作为参数注入到函数中。