Skip to content
全部文档

验证

简介

验证规则可添加到任意 字段

在 Laravel 中,验证规则通常定义为数组(如 ['required', 'max:255'])或组合字符串(如 required|max:255)。若你仅在后端使用简单的 form request,这样即可。但 Filament 还能为用户提供前端验证,让他们在发起任何后端请求之前就能修正错误。

Filament 包含许多 专用验证方法,你也可以使用任意 其他 Laravel 验证规则,包括 自定义验证规则

带验证错误的表单带验证错误的表单

WARNING

部分默认 Laravel 验证规则依赖正确的属性名,通过 rule()/rules() 传入时可能无效。尽可能使用专用验证方法。

可用规则

有效 URL

根据 PHP 的 dns_get_record() 函数,该字段必须具有有效的 A 或 AAAA 记录。参见 Laravel 文档。

php
Field::make('name')->activeUrl()

之后(日期)

字段值必须是给定日期之后的值。参见 Laravel 文档。

php
Field::make('start_date')->after('tomorrow')

或者,你可以传入另一个字段名以进行比较:

php
Field::make('start_date')
Field::make('end_date')->after('start_date')

之后或等于(日期)

字段值必须是给定日期之后或等于该日期的日期。参见 Laravel 文档。

php
Field::make('start_date')->afterOrEqual('tomorrow')

或者,你可以传入另一个字段名以进行比较:

php
Field::make('start_date')
Field::make('end_date')->afterOrEqual('start_date')

字母

字段必须完全由字母字符组成。参见 Laravel 文档。

php
Field::make('name')->alpha()

字母、数字、破折号与下划线

字段可以包含字母数字字符,以及破折号与下划线。参见 Laravel 文档。

php
Field::make('name')->alphaDash()

字母数字

字段必须完全由字母数字字符组成。参见 Laravel 文档。

php
Field::make('name')->alphaNum()

ASCII

字段必须完全由 7 位 ASCII 字符组成。参见 Laravel 文档。

php
Field::make('name')->ascii()

之前(日期)

字段值必须是给定日期之前的日期。参见 Laravel 文档。

php
Field::make('start_date')->before('first day of next month')

或者,你可以传入另一个字段名以进行比较:

php
Field::make('start_date')->before('end_date')
Field::make('end_date')

之前或等于(日期)

字段值必须是给定日期之前或等于该日期的日期。参见 Laravel 文档。

php
Field::make('start_date')->beforeOrEqual('end of this month')

或者,你可以传入另一个字段名以进行比较:

php
Field::make('start_date')->beforeOrEqual('end_date')
Field::make('end_date')

确认

字段必须有一个匹配的 {field}_confirmation 字段。参见 Laravel 文档。

php
Field::make('password')->confirmed()
Field::make('password_confirmation')

不同

字段值必须与另一个字段不同。参见 Laravel 文档。

php
Field::make('backup_email')->different('email')

不以…开头

字段不得以给定值之一开头。参见 Laravel 文档。

php
Field::make('name')->doesntStartWith(['admin'])

不以…结尾

字段不得以给定值之一结尾。参见 Laravel 文档。

php
Field::make('name')->doesntEndWith(['admin'])

以…结尾

字段必须以给定值之一结尾。参见 Laravel 文档。

php
Field::make('name')->endsWith(['bot'])

枚举

字段必须包含有效的枚举值。参见 Laravel 文档。

php
Field::make('status')->enum(MyStatus::class)

存在

字段值必须在数据库中存在。参见 Laravel 文档。

php
Field::make('invitation')->exists()

默认情况下,若表单 已注册模型,将在该模型中搜索。你可以指定自定义表名或模型进行搜索:

php
use App\Models\Invitation;

Field::make('invitation')->exists(table: Invitation::class)

默认情况下,将使用字段名作为搜索列。你可以指定自定义列进行搜索:

php
Field::make('invitation')->exists(column: 'id')

你可以通过向 modifyRuleUsing 参数传入 闭包 进一步自定义该规则:

php
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,并应用模型上定义的任何全局作用域(包括软删除与多租户):

php
use Filament\Forms\Components\TextInput;

TextInput::make('email')
    ->scopedExists()

若希望修改用于检查存在性的 Eloquent 查询(包括移除全局作用域),可以向 modifyQueryUsing 参数传入函数:

php
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 文档。

php
Field::make('name')->filled()

大于

字段值必须大于另一个字段。参见 Laravel 文档。

php
Field::make('newNumber')->gt('oldNumber')

大于或等于

字段值必须大于或等于另一个字段。参见 Laravel 文档。

php
Field::make('newNumber')->gte('oldNumber')

十六进制颜色

字段值必须是有效的十六进制格式颜色。参见 Laravel 文档。

php
Field::make('color')->hexColor()

包含于

字段必须包含在给定的值列表中。参见 Laravel 文档。

php
Field::make('status')->in(['pending', 'completed'])

切换按钮复选框列表单选选择 字段会根据其可用选项自动应用 in() 规则,因此你无需手动添加。

IP 地址

字段必须是 IP 地址。参见 Laravel 文档。

php
Field::make('ip_address')->ip()
Field::make('ip_address')->ipv4()
Field::make('ip_address')->ipv6()

JSON

字段必须是有效的 JSON 字符串。参见 Laravel 文档。

php
Field::make('ip_address')->json()

小于

字段值必须小于另一个字段。参见 Laravel 文档。

php
Field::make('newNumber')->lt('oldNumber')

小于或等于

字段值必须小于或等于另一个字段。参见 Laravel 文档。

php
Field::make('newNumber')->lte('oldNumber')

MAC 地址

字段必须是 MAC 地址。参见 Laravel 文档。

php
Field::make('mac_address')->macAddress()

倍数

字段必须是某值的倍数。参见 Laravel 文档。

php
Field::make('number')->multipleOf(2)

不包含于

字段不得包含在给定的值列表中。参见 Laravel 文档。

php
Field::make('status')->notIn(['cancelled', 'rejected'])

不匹配正则

字段不得匹配给定的正则表达式。参见 Laravel 文档。

php
Field::make('email')->notRegex('/^.+$/i')

可为空

字段值可以为空。若未出现 required 规则,默认会应用此规则。参见 Laravel 文档。

php
Field::make('name')->nullable()

禁止

字段值必须为空。参见 Laravel 文档。

php
Field::make('name')->prohibited()

在…时禁止

仅当 其他指定字段具有给定值之一时,该字段必须为空。参见 Laravel 文档。

php
Field::make('name')->prohibitedIf('field', 'value')

除非…否则禁止

除非 其他指定字段具有给定值之一,否则该字段必须为空。参见 Laravel 文档。

php
Field::make('name')->prohibitedUnless('field', 'value')

禁止其他字段

若该字段不为空,则所有其他指定字段必须为空。参见 Laravel 文档。

php
Field::make('name')->prohibits('field')

Field::make('name')->prohibits(['field', 'another_field'])

必填

字段值不得为空。参见 Laravel 文档。

php
Field::make('name')->required()

将字段标记为必填

默认情况下,必填字段会在其标签旁显示星号 *。在所有字段都必填的表单上,或者更适合为可选字段添加 提示 时,你可能希望隐藏该星号:

php
use Filament\Forms\Components\TextInput;

TextInput::make('name')
    ->required() // Adds validation to ensure the field is required
    ->markAsRequired(false) // Removes the asterisk

若字段未使用 required(),但仍希望显示星号 *,也可以使用 markAsRequired()

php
use Filament\Forms\Components\TextInput;

TextInput::make('name')
    ->markAsRequired()

在…时必填

仅当 其他指定字段具有给定值之一时,该字段值不得为空。参见 Laravel 文档。

php
Field::make('name')->requiredIf('field', 'value')

在…被接受时必填

仅当 其他指定字段等于 "yes"、"on"、1、"1"、true 或 "true" 时,该字段值不得为空。参见 Laravel 文档。

php
Field::make('name')->requiredIfAccepted('field')

除非…否则必填

除非 其他指定字段具有给定值之一,否则该字段值不得为空。参见 Laravel 文档。

php
Field::make('name')->requiredUnless('field', 'value')

与…同时必填

仅当 其他指定字段中任一不为空时,该字段值不得为空。参见 Laravel 文档。

php
Field::make('name')->requiredWith('field,another_field')

与全部…同时必填

仅当 其他指定字段全部不为空时,该字段值不得为空。参见 Laravel 文档。

php
Field::make('name')->requiredWithAll('field,another_field')

在缺少…时必填

仅当 其他指定字段中任一无值时,该字段值不得为空。参见 Laravel 文档。

php
Field::make('name')->requiredWithout('field,another_field')

在全部缺少…时必填

仅当 其他指定字段全部为空时,该字段值不得为空。参见 Laravel 文档。

php
Field::make('name')->requiredWithoutAll('field,another_field')

正则

字段必须匹配给定的正则表达式。参见 Laravel 文档。

php
Field::make('email')->regex('/^.+@.+$/i')

相同

字段值必须与另一个字段相同。参见 Laravel 文档。

php
Field::make('password')->same('passwordConfirmation')

以…开头

字段必须以给定值之一开头。参见 Laravel 文档。

php
Field::make('name')->startsWith(['a'])

字符串

字段必须是字符串。参见 Laravel 文档。

php
Field::make('name')->string()

唯一

字段值不得在数据库中已存在。参见 Laravel 文档。

php
Field::make('email')->unique()

若你的 Filament 表单已关联 Eloquent 模型(例如在 面板资源 中),Filament 会使用该模型。你也可以指定自定义表名或模型进行搜索:

php
use App\Models\User;

Field::make('email')->unique(table: User::class)

默认情况下,将使用字段名作为搜索列。你可以指定自定义列进行搜索:

php
Field::make('email')->unique(column: 'email_address')

通常,你希望在唯一性验证期间忽略某个给定模型。例如,考虑一个包含用户姓名、电子邮件地址与位置的「更新个人资料」表单。你可能想验证电子邮件地址是否唯一。然而,若用户只更改了姓名字段而未更改电子邮件字段,你不希望因该用户已是该电子邮件地址的所有者而抛出验证错误。若你的 Filament 表单已关联 Eloquent 模型(例如在 面板资源 中),Filament 会忽略它。

若要阻止 Filament 忽略当前 Eloquent 记录,可以向 ignoreRecord 参数传入 false

php
Field::make('email')->unique(ignoreRecord: false)

或者,要忽略你选择的 Eloquent 记录,可以将其传给 ignorable 参数:

php
Field::make('email')->unique(ignorable: $ignoredUser)

你可以通过向 modifyRuleUsing 参数传入 闭包 进一步自定义该规则:

php
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,并应用模型上定义的任何全局作用域(包括软删除与多租户):

php
use Filament\Forms\Components\TextInput;

TextInput::make('email')
    ->scopedUnique()

若希望修改用于检查唯一性的 Eloquent 查询(包括移除全局作用域),可以向 modifyQueryUsing 参数传入函数:

php
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

php
Field::make('identifier')->ulid()

UUID

字段必须是有效的 RFC 4122(版本 1、3、4 或 5)通用唯一标识符(UUID)。参见 Laravel 文档。

php
Field::make('identifier')->uuid()

其他规则

你可以使用 rules() 方法为任意字段添加其他验证规则:

php
TextInput::make('slug')->rules(['alpha_dash'])

完整的验证规则列表可在 Laravel 文档 中找到。

自定义规则

你可以像在 Laravel 中一样使用任意自定义验证规则:

php
TextInput::make('slug')->rules([new Uppercase()])

你也可以使用 闭包规则

php
use Closure;

TextInput::make('slug')->rules([
    fn (): Closure => function (string $attribute, $value, Closure $fail) {
        if ($value === 'foo') {
            $fail('The :attribute is invalid.');
        }
    },
])

你可以将 $get工具注入 到自定义规则中,例如需要引用表单中其他字段值时。为此,将闭包规则包装在另一个返回它的函数中:

php
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() 方法:

php
use Filament\Forms\Components\TextInput;

TextInput::make('name')
    ->validationAttribute('full name')

TIP

除了接受静态值,validationAttribute() 方法也接受函数以动态计算该值。你可以将各种工具(utilities)作为参数注入到函数中。

验证消息

默认使用 Laravel 的验证错误消息。要自定义错误消息,请使用 validationMessages() 方法:

php
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() 方法:

php
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() 方法:

php
use Filament\Forms\Components\TextInput;

TextInput::make('name')
    ->required()
    ->saved(false)
    ->validatedWhenNotDehydrated(false)

TIP

除了接受静态值,validatedWhenNotDehydrated() 方法也接受函数以动态计算该值。你可以将各种工具(utilities)作为参数注入到函数中。