Validate可用验证规则

2019-10-08 15:12:18   PHP

  validate  

accepted
验证字段必须是 yes, on, 1,或 true。这在确认「服务条款」是否同意时相当有用。

active_url
根据 PHP 函数 dns_get_record ,验证字段必须具有有效的 A 或 AAAA 记录。

after:date
验证字段必须是给定日期之后的值。日期值将传递到 PHP 函数 strtotime :

'start_date' => 'required|date|after:tomorrow'
您可以指定另一个要与日期进行比较的字段,而不是传递要由 strtotime 处理的日期字符串:

'finish_date' => 'required|date|after:start_date'

after_or_equal:date
验证字段必须是在给定日期之后或与此日期相同的值。更多信息,请参阅 after 。

alpha
验证字段必须完全由字母构成。

alpha_dash
验证字段可能包含字母、数字,以及破折号 (-) 和下划线 ( _ )。

alpha_num
验证字段必须是完全是字母、数字。

array
验证的字段必须是一个 PHP 数组。

bail
在第一次验证失败后停止运行验证规则。

before:date
正在验证的字段必须是给定日期之前的值。这个日期将传递到 PHP 的 strtotime 函数中。此外,与 after 规则一样,另一个正在验证的字段可以作为 date 的值。

before_or_equal:date
验证字段必须是在给定日期之前或与之相同的日期。这个日期值将会被传递给 PHP 的 strtotime 函数来计算。

between:min,max
验证字段的大小必须在给定的 min 和 max 之间。字符串、数字、数组和文件的计算方式都使用 size 方法。

boolean
验证的字段必须可以转换为 Boolean 类型。 可接受的输入为 true , false , 1 , 0 , "1" 和 "0" 。

confirmed
验证字段必须具有匹配字段 foo_confirmation 。例如,验证字段为 password ,输入中必须存在与之匹配的 password_confirmation 字段。

date
根据 PHP strtotime 函数,验证的字段必须是有效的日期。

date_equals:date
验证字段必须等于给定日期。日期将传递到 PHP strtotime 函数。

date_format:format
验证字段必须匹配给定的日期格式。当验证某个字段的时候,你应该 只使用 date 或者 date_format ,而不是同时使用。此验证规则支持 PHP 所有的 DateTime 类。

different:field
验证的字段值必须与字段 field 的值不同。

digits:value
验证的字段必须为 numeric ,并且必须具有确切长度 value。

digits_between:min,max
验证字段的长度必须在给定的 min 和 max 之间。

dimensions
验证的文件必须是图片并且图片比例必须符合规则:

'avatar' => 'dimensions:min_width=100,min_height=200'
可用的规则为:min_width, max_width, min_height, max_height, width, height, ratio。

ratio  约束应该表示为宽度除以高度。 这可以通过像 3/2 这样的语句或像 1.5 这样的 float 来指定:

'avatar' => 'dimensions:ratio=3/2'
由于此规则需要多个参数,因此你可以 Rule::dimensions 方法来构造可读性高的规则:

use Illuminate\Validation\Rule;

Validator::make($data, [
    'avatar' => [
        'required',
        Rule::dimensions()->maxWidth(1000)->maxHeight(500)->ratio(3 / 2),
    ],
]);

distinct
验证数组时,指定的字段不能有任何重复值。

'foo.*.id' => 'distinct'

email
验证的字段必须符合 e-mail 地址格式。当前版本,此种验证规则由 egulias/email-validator 提供支持。默认使用 RFCValidation 验证样式,但你也可以使其他验证样式:

'email' => 'email:rfc,dns'
例子使用 RFCValidation 和 DNSCheckValidation 验证样式。所有可用验证样式列表:

rfc: RFCValidation
strict: NoRFCWarningsValidation
dns: DNSCheckValidation
spoof: SpoofCheckValidation
filter: FilterEmailValidation
当下版本 filter 验证规则使用 PHP 的 filter_var 方法进行验证,在 5.8 版本接入 Laravel 。

ends_with:foo,bar,...
验证的字段必须以给定的值之一结尾。

exists:table,column
验证的字段必须存在于给定的数据库表中。

Exists 规则的基本用法
'state' => 'exists:states'
如果未指定 column 选项,则将使用字段名称。

指定列名
'state' => 'exists:states,abbreviation'
如果你需要指定 exists 方法用来查询的数据库。你可以通过使用「点」语法将数据库的名称添加到数据表前面来实现这个目的:

'email' => 'exists:connection.staff,email'
如果要自定义验证规则执行的查询,可以使用 Rule 类来定义规则。在这个例子中,我们使用数组指定验证规则,而不是使用 | 字符来分隔它们:

use Illuminate\Validation\Rule;

Validator::make($data, [
    'email' => [
        'required',
        Rule::exists('staff')->where(function ($query) {
            $query->where('account_id', 1);
        }),
    ],
]);

file
验证的字段必须是成功上传的文件。

filled
验证的字段在存在时不能为空。

gt:field
验证字段必须大于给定的 field。两个字段必须是相同的类型。字符串、数字、数组和文件都使用 size 进行相同的评估。

gte:field
验证字段必须大于或等于给定的 field。两个字段必须是相同的类型。字符串、数字、数组和文件都使用 size 进行相同的评估。

image
验证的文件必须是图片 (jpeg, png, bmp, gif, svg, or webp)

in:foo,bar,...
验证字段必须包含在给定的值列表中。由于此规则通常要求您 implode 数组,因此可以使用 Rule :: in 方法流畅地构造规则:

use Illuminate\Validation\Rule;

Validator::make($data, [
    'zones' => [
        'required',
        Rule::in(['first-zone', 'second-zone']),
    ],
]);

in_array:anotherfield.*
验证的字段必须存在于另一个字段  anotherfield  的值中。

integer
验证的字段必须是整数。

{注} 此种验证规则不是验证数据是 “integer” 类型,仅验证字符串或数值包含一个 integer.

ip
验证的字段必须是 IP 地址。

ipv4
验证的字段必须是 IPv4 地址。

ipv6
验证的字段必须是 IPv6 地址。

json
验证的字段必须是有效的 JSON 字符串。

lt:field
验证的字段必须小于给定的 field.。这两个字段必须是相同的类型。字符串、数值、数组和文件大小的计算方式与 size 方法进行评估。

lte:field
验证中的字段必须小于或等于给定的 字段 。这两个字段必须是相同的类型。字符串、数值、数组和文件大小的计算方式与 size 方法进行评估。

max:value
验证中的字段必须小于或等于 value。字符串、数字、数组或是文件大小的计算方式都用 size 规则。

mimetypes:text/plain,...
验证的文件必须具备与列出的其中一个扩展相匹配的 MIME 类型:

'video' => 'mimetypes:video/avi,video/mpeg,video/quicktime'
为了确定上传文件的 MIME,框架将会读取文件,然后自动推测文件 MIME 类型,这可能与客户端提供的 MIME 类型不一致 。

mimes:foo,bar,...
验证的文件必须具有与列出的其中一个扩展名相对应的 MIME 类型。

MIME 规则基本用法
'photo' => 'mimes:jpeg,bmp,png'
即使你可能只需要验证指定扩展名,但此规则实际上会去验证文件的 MIME 类型,其通过读取文件内容来推测它的 MIME 类型。

可以在以下链接中找到完整的 MIME 类型列表及相对应的扩展名: https://svn.apache.org/repos/asf/httpd/htt...

min:value
验证字段必须具有最小值。 字符串,数值,数组,文件大小的计算方式都与 size 规则一致.

not_in:foo,bar,...
验证字段不能包含在给定的值的列表中。 使用 Rule::notIn 方法可以更流畅的构建这个规则:

use Illuminate\Validation\Rule;

Validator::make($data, [
    'toppings' => [
        'required',
        Rule::notIn(['sprinkles', 'cherries']),
    ],
]);

not_regex:pattern
验证字段必须与给定的正则表达式不匹配。

验证时,这个规则使用 PHP preg_match 函数。指定的模式应遵循 preg_match 所需的相同格式,也包括有效的分隔符。 例如: 'email' => 'not_regex:/^.+$/i'.

注意: 当使用 regex / not_regex 模式时, 可能需要在数组中指定规则,而不是使用 | 分隔符 ,特别是在正则表达式包含 | 字符 的情况下。

nullable
验证字段可以为 null。这在验证基本数据类型时特别有用,例如可以包含空值的字符串和整数。

numeric
验证字段必须为数值。

present
验证字段必须存在于输入数据中,但可以为空。

regex:pattern
验证字段必须与给定的正则表达式匹配。

验证时,这个规则使用 PHP 的 preg_match 函数。 指定的模式应遵循 preg_match 所需的相同格式,也包括有效的分隔符。 例如: 'email' => 'not_regex:/^.+$/i' 。

注意: 当使用 regex / not_regex 模式时, 可能需要在数组中指定规则,而不是使用 | 分隔符 ,特别是在正则表达式包含 | 字符 的情况下。

required
验证的字段必须存在于输入数据中,而不是空。如果满足以下条件之一,则字段被视为「空」:

值为 null 。
值为空字符串。
值为空数组或空 Countable 对象。
值为无路径的上传文件。

required_if:anotherfield,value,...
如果其它字段 _anotherfield_ 为任一值 _value_ ,则此验证字段必须存在且不为空。

如果您需要构造更复杂的条件 required_if 规则, 您可以使用 Rule::requiredIf 方法。这个方法可以接受一个布尔值或是一个闭包函数,当传递闭包函数时,闭包函数应该返回 true 或 false ,以表明是否需要验证此字段:

use Illuminate\Validation\Rule;

Validator::make($request->all(), [
    'role_id' => Rule::requiredIf($request->user()->is_admin),
]);

Validator::make($request->all(), [
    'role_id' => Rule::requiredIf(function () use ($request) {
        return $request->user()->is_admin;
    }),
]);

required_unless:anotherfield,value,...
如果其它字段 _anotherfield_ 不等于任一值 _value_ ,则此验证字段必须存在且不为空。

required_with:foo,bar,...
在其他任一指定字段出现时,验证的字段才必须存在且不为空。

required_with_all:foo,bar,...
只有在其他指定字段全部出现时,验证的字段才必须存在且不为空。

required_without:foo,bar,...
在其他指定任一字段不出现时,验证的字段才必须存在且不为空。

required_without_all:foo,bar,...
只有在其他指定字段全部不出现时,验证的字段才必须存在且不为空。

same:field
验证字段必须与给定字段相匹配。

size:value
验证字段必须与给定值的大小一致。对于字符串,value 对应字符数。对于数字,value 对应给定的整数值。对于数组,size 对应数组的 count 值。对于文件,size 对应文件大小(单位 kb)。

starts_with:foo,bar,...
验证字段必须以给定值之一开头。

string
验证字段必须是一个字符串。如果允许这个字段为 null,需要给这个字段分配 nullable 规则。

timezone
验证字段必须为符合 PHP 函数 timezone_identifiers_list 所定义的有效时区标识。

unique:table,column,except,idColumn
验证字段在给定的数据库表中必须是唯一的。

指定自定义列名:

column 选项可用于指定相应数据库列的字段。 如果未指定 column 选项,则使用字段本身名称。

'email' => 'unique:users,email_address'
自定义数据库连接

有时,你可能需要为验证器创建的数据库查询设置自定义连接。上面的例子中,将 unique:users 设置为验证规则,等于使用默认数据库连接来查询数据库。如果要对其进行修改,请使用「点」语法来指定连接和表名:

'email' => 'unique:connection.users,email_address'
强迫 Unique 规则忽略指定 ID :

有时,你可能希望在进行字段唯一性验证时忽略指定 ID 。例如, 在「更新个人资料」页面会包含用户名、邮箱和地点。这时你会想要验证更新的 E-mail 值是否唯一。如果用户仅更改了用户名字段而没有改 E-mail 字段,就不需要抛出验证错误,因为此用户已经是这个 E-mail 的拥有者了。

使用 Rule 类定义规则来指示验证器忽略用户的 ID 。这个例子中通过数组来指定验证规则,而不是使用 | 字符来分隔:

use Illuminate\Validation\Rule;

Validator::make($data, [
    'email' => [
        'required',
        Rule::unique('users')->ignore($user->id),
    ],
]);
{备注} 您永远不应该将任何用户控制的请求输入传递给 ignore 方法。您应该只通过 Eloquent 模型的实例来传递系统生成的唯一 ID ,例如自动递增 ID 或 UUID 。 否则,您的应用程序将更容易受到 SQL 注入攻击。

您可以传递整个模型实例,而不是将模型实例的主键值 传递给 ignore 方法。 Laravel 将自动从模型实例中获取主键值:

Rule::unique('users')->ignore($user)
如果您的数据表使用的主键名称不是 id ,那就在调用 ignore 方法时指定字段的名称:

Rule::unique('users')->ignore($user->id, 'user_id')
默认情况下, unique 规则将检查与要验证字段名称相匹配的列的唯一性。 但是,您可以传递一个不同的列名作为 unique 方法的第二个参数:

Rule::unique('users', 'email_address')->ignore($user->id),
增加额外的 Where 语句:

您也可以通过 where 方法指定额外的查询条件。例如, 我们添加 account_id 为 1 的约束:

'email' => Rule::unique('users')->where(function ($query) {
    return $query->where('account_id', 1);
})

url
验证的字段必须是有效的 URL。

uuid
验证字段必须是有效的 RFC 4122(版本 1,3,4 或 5)通用唯一标识符(UUID)。

按条件增加规则
存在时则验证
在某些情况下,你可能希望将要验证的字段存在于输入数组中时,才对该字段执行验证。可以在规则列表中增加 sometimes 来实现:

$v = Validator::make($data, [
    'email' => 'sometimes|required|email',
]);
在上面的例子中, email 字段只有在 $data 数组中存在时才会被验证。

Tip:如果你尝试验证应该始终存在但可能为空的字段,请查阅 可选字段的注意事项

复杂的条件验证
有时候你可能需要增加基于更复杂的条件逻辑的验证规则。例如,你可以希望某个指定字段在另一个字段的值超过 100 时才为必填。或者当某个指定字段存在时,另外两个字段才能具有给定的值。增加这样的验证条件并不难。首先,使用 静态规则 创建一个 Validator 实例:

$v = Validator::make($data, [
    'email' => 'required|email',
    'games' => 'required|numeric',
]);
假设我们有一个专为游戏收藏家所设计的网页应用程序。如果游戏收藏家收藏超过一百款游戏,我们会希望他们来说明下为什么他们会拥有这么多游戏。比如说他们有可能经营了一家游戏分销商店,或者只是为了享受收集的乐趣。为了在特定条件下加入此验证需求,可以在 Validator 实例中使用 sometimes 方法。

$v->sometimes('reason', 'required|max:500', function ($input) {
    return $input->games >= 100;
});
传入 sometimes 方法的第一个参数是要用来验证的字段名称。第二个参数是我们想使用的验证规则。 闭包 作为第三个参数传入,如果其返回 true , 则额外的规则就会被加入。这个方法可以轻松地创建复杂的条件验证。你甚至可以一次对多个字段增加条件验证:

$v->sometimes(['reason', 'cost'], 'required', function ($input) {
    return $input->games >= 100;
});
Tip:传入 闭包 的 $input 参数是 Illuminate\Support\Fluent 的一个实例,可用来访问你的输入或文件对象。

验证数组
验证表单的输入为数组的字段也不难。你可以使用 「点」方法来验证数组中的属性。例如,如果传入的 HTTP 请求中包含 photos[profile] 字段, 可以如下验证:

$validator = Validator::make($request->all(), [
    'photos.profile' => 'required|image',
]);
你也可以验证数组中的每个元素。例如,要验证指定数组输入字段中的每一个 email 是唯一的,可以这么做:

$validator = Validator::make($request->all(), [
    'person.*.email' => 'email|unique:users',
    'person.*.first_name' => 'required_with:person.*.last_name',
]);
同理,你可以在语言文件定义验证信息时使用 * 字符,为基于数组的字段使用单个验证消息:

'custom' => [
    'person.*.email' => [
        'unique' => 'Each person must have a unique e-mail address',
    ]
],

自定义验证规则

使用规则对象
Laravel 提供了许多有用的验证规则;同时也支持自定义规则。注册自定义验证规则的方法之一,就是使用规则对象。可以使用 Artisan 命令 make:rule 来生成新的规则对象。接下来,让我们用这个命令生成一个验证字符串是否是大写的规则。Laravel 会将新的规则存放在 app/Rules 目录中:

php artisan make:rule Uppercase
一旦创建了规则,我们就可以定义它的行为。规则对象包含两个方法: passes 和 message。passes 方法接收属性值和名称,并根据属性值是否符合规则而返回  true 或 false。 message 方法应返回验证失败时应使用的验证错误消息:

<?php

namespace App\Rules;

use Illuminate\Contracts\Validation\Rule;

class Uppercase implements Rule
{
    /**
     * 确定验证规则是否通过。
     *
     * @param  string  $attribute
     * @param  mixed  $value
     * @return bool
     */
    public function passes($attribute, $value)
    {
        return strtoupper($value) === $value;
    }

    /**
     * 获取验证错误消息。
     *
     * @return string
     */
    public function message()
    {
        return 'The :attribute must be uppercase.';
    }
}
当然, 如果你希望从翻译文件中返回一个错误消息,你可以从 message 方法中调用辅助函数 trans:

/**
 * 获取验证错误消息。
 *
 * @return string
 */
public function message()
{
    return trans('validation.uppercase');
}
一旦规则对象被定义好后,你可以通过将规则对象的实例和其他验证规则一起来传递给验证器:

use App\Rules\Uppercase;

$request->validate([
    'name' => ['required', 'string', new Uppercase],
]);

使用闭包
如果你在应用程序中只需要一次自定义规则的功能,则可以使用闭包代替规则对象。闭包接收属性的名称、属性的值、失败回调,如果验证失败需要调用 $fail:

$validator = Validator::make($request->all(), [
    'title' => [
        'required',
        'max:255',
        function ($attribute, $value, $fail) {
            if ($value === 'foo') {
                $fail($attribute.' is invalid.');
            }
        },
    ],
]);

使用扩展
注册自定义的验证规则的另一种方法是使用 Validator facade 中的 extend 方法。让我们在 服务容器 中使用这个方法来注册自定义验证规则:

<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\Validator;

class AppServiceProvider extends ServiceProvider
{
    /**
     * 注册服务提供器。
     *
     * @return void
     */
    public function register()
    {
        //
    }

    /**
     * 引导应用程序。
     *
     * @return void
     */
    public function boot()
    {
        Validator::extend('foo', function ($attribute, $value, $parameters, $validator) {
            return $value == 'foo';
        });
    }
}
自定义的验证闭包接收四个参数:要被验证的属性名称 $attribute、属性的值 $value、传入验证规则的参数数组 $parameters 、以及 Validator 实列。

除了使用闭包,你也可以传入类和方法到 extend 方法中:

Validator::extend('foo', 'FooValidator@validate');
定义错误消息
你还需要为自定义规则定义错误信息。你可以使用内联自定义消息数组或者在验证语言文件中添加条目来实现这一功能。 消息应该被放到数组的第一位, 而不是在只用于存放属性指定错误信息的 custom 数组内:

"foo" => "Your input was invalid!",

"accepted" => "The :attribute must be accepted.",

// 其余的验证错误消息...
当创建一个自定义验证规则时,你可能有时候需要为错误信息定义自定义占位符。可以通过创建自定义验证器然后调用 Validator 门面上的  replacer 方法。你可以在 服务容器 的 boot 方法中执行如下操作:

/**
 * 引导应用程序。
 *
 * @return void
 */
public function boot()
{
    Validator::extend(...);

    Validator::replacer('foo', function ($message, $attribute, $rule, $parameters) {
        return str_replace(...);
    });
}

隐式扩展
默认情况下,当所要验证的属性不存在或包含一个空字符串时,使用包含自定义扩展的正常的验证规则是不会执行的。例如,unique 规则将不会检验空字符串:

$rules = ['name' => 'unique:users,name'];

$input = ['name' => ''];

Validator::make($input, $rules)->passes(); // true
如果即使属性为空也要验证规则,则一定要暗示属性是必须的。要创建这样一个「隐式」扩展,可以使用 Validator::extendImplicit() 方法:

Validator::extendImplicit('foo', function ($attribute, $value, $parameters, $validator) {
    return $value == 'foo';
});
注意:「隐式」扩展只暗示该属性是必需的。至于它到底是缺失还是空值这取决于你。

隐式规则对象
如果你想要在属性为空时执行规则对象,你应该实现 Illuminate\Contracts\Validation\ImplicitRule 接口。这个接口将充当验证器的「标记接口」;因此,它不包含你要实现的任何方法。