Validation

Introduction

Laravel 提供了几种不同的方法来验证应用程序的传入数据。这是最常见的使用validate 方法适用于所有传入的 HTTP 请求。但是,我们还将讨论其他验证方法。

Laravel 包含各种方便的验证规则,您可以将它们应用于数据,甚至提供验证值在给定数据库表中是否唯一的能力。我们将详细介绍这些验证规则中的每一个,以便您熟悉 Laravel 的所有验证功能。

验证快速入门

要了解 Laravel 强大的验证功能,让我们看一个验证表单并向用户显示错误消息的完整示例。通过阅读这个高级概述,您将能够对如何使用 Laravel 验证传入的请求数据有一个很好的总体了解:

定义路线

首先,假设我们在我们的文件中定义了以下路由routes/web.php 文件:

use App\Http\Controllers\PostController;

Route::get('/post/create', [PostController::class, 'create']);
Route::post('/post', [PostController::class, 'store']);

GET 路由将显示一个表单供用户创建新的博客文章,而POST route 会将新的博客文章存储在数据库中。

创建控制器

接下来,让我们看一下一个简单的控制器,它处理对这些路由的传入请求。我们将离开store 方法暂时为空:

<?php

namespace App\Http\Controllers;

use App\Http\Controllers\Controller;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\View\View;

class PostController extends Controller
{
    /**
     * Show the form to create a new blog post.
     */
    public function create(): View
    {
        return view('post.create');
    }

    /**
     * Store a new blog post.
     */
    public function store(Request $request): RedirectResponse
    {
        // Validate and store the blog post...

        $post = /** ... */

        return to_route('post.show', ['post' => $post->id]);
    }
}

编写验证逻辑

现在我们准备填写我们的store 方法与验证新博客文章的逻辑。为此,我们将使用validate 提供的方法Illuminate\Http\Request 目的。如果验证规则通过,您的代码将继续正常执行;然而,如果验证失败,一个Illuminate\Validation\ValidationException 将抛出异常,并自动将正确的错误响应发送回用户。

如果在传统 HTTP 请求期间验证失败,将生成对先前 URL 的重定向响应。如果传入请求是 XHR 请求,则包含验证错误消息的 JSON 响应 将被退回。

为了更好地了解validate 方法,让我们跳回到store 方法:

/**
 * Store a new blog post.
 */
public function store(Request $request): RedirectResponse
{
    $validated = $request->validate([
        'title' => 'required|unique:posts|max:255',
        'body' => 'required',
    ]);

    // The blog post is valid...

    return redirect('/posts');
}

如您所见,验证规则被传递到validate 方法。别担心 - 所有可用的验证规则都是documented.同样,如果验证失败,将自动生成正确的响应。如果验证通过,我们的控制器将继续正常执行。

或者,验证规则可以指定为规则数组而不是单个| 分隔字符串:

$validatedData = $request->validate([
    'title' => ['required', 'unique:posts', 'max:255'],
    'body' => ['required'],
]);

此外,您可以使用validateWithBag 验证请求并将任何错误消息存储在命名错误包:

$validatedData = $request->validateWithBag('post', [
    'title' => ['required', 'unique:posts', 'max:255'],
    'body' => ['required'],
]);

在第一次验证失败时停止

有时您可能希望在第一次验证失败后停止对属性运行验证规则。为此,分配bail 属性规则:

$request->validate([
    'title' => 'bail|required|unique:posts|max:255',
    'body' => 'required',
]);

在这个例子中,如果unique 规则title 属性失败,max 规则不会被检查。规则将按照分配的顺序进行验证。

关于嵌套属性的注释

如果传入的 HTTP 请求包含“嵌套”字段数据,您可以使用“点”语法在验证规则中指定这些字段:

$request->validate([
    'title' => 'required|unique:posts|max:255',
    'author.name' => 'required',
    'author.description' => 'required',
]);

另一方面,如果您的字段名称包含文字句点,您可以通过使用反斜杠转义句点来明确防止将其解释为“点”语法:

$request->validate([
    'title' => 'required|unique:posts|max:255',
    'v1\.0' => 'required',
]);

显示验证错误

那么,如果传入的请求字段没有通过给定的验证规则怎么办?如前所述,Laravel 会自动将用户重定向回他们之前的位置。此外,所有验证错误和请求输入 会自动成为闪现到会话.

一个$errors 变量由你的应用程序的所有视图共享Illuminate\View\Middleware\ShareErrorsFromSession 中间件,由web 中间件组。当应用此中间件时$errors 变量将始终在您的视图中可用,使您可以方便地假设$errors 变量总是被定义并且可以安全地使用。这$errors 变量将是一个实例Illuminate\Support\MessageBag.有关使用此对象的更多信息,查看它的文档.

因此,在我们的示例中,用户将被重定向到我们控制器的create 验证失败时的方法,允许我们在视图中显示错误消息:

<!-- /resources/views/post/create.blade.php -->

<h1>Create Post</h1>

@if ($errors->any())
    <div class="alert alert-danger">
        <ul>
            @foreach ($errors->all() as $error)
                <li>{{ $error }}</li>
            @endforeach
        </ul>
    </div>
@endif

<!-- Create Post Form -->

自定义错误消息

Laravel 的内置验证规则每个都有一条错误消息,位于您的应用程序的lang/en/validation.php 文件。在此文件中,您将找到每个验证规则的翻译条目。您可以根据应用程序的需要自由更改或修改这些消息。

此外,您可以将此文件复制到另一个语言目录,以将消息翻译为您的应用程序语言。要了解有关 Laravel 本地化的更多信息,请查看完整的本地化文档.

Warning 默认情况下,Laravel 应用程序框架不包括lang 目录。如果你想自定义 Laravel 的语言文件,你可以通过lang:publish 工匠命令。

XHR 请求和验证

在本例中,我们使用传统的表单向应用程序发送数据。然而,许多应用程序从 JavaScript 驱动的前端接收 XHR 请求。当使用validate 在 XHR 请求期间,Laravel 不会生成重定向响应。相反,Laravel 生成一个包含所有验证错误的 JSON 响应.此 JSON 响应将与 422 HTTP 状态代码一起发送。

@error 指示

您可以使用@error Blade 指令来快速确定给定属性是否存在验证错误消息。在一个@error 指令,你可以回显$message 显示错误消息的变量:

<!-- /resources/views/post/create.blade.php -->

<label for="title">Post Title</label>

<input id="title"
    type="text"
    name="title"
    class="@error('title') is-invalid @enderror">

@error('title')
    <div class="alert alert-danger">{{ $message }}</div>
@enderror

如果您正在使用命名错误包,您可以将错误包的名称作为第二个参数传递给@error 指示:

<input ... class="@error('title', 'post') is-invalid @enderror">

重新填充表格

当 Laravel 由于验证错误而生成重定向响应时,框架会自动将请求的所有输入闪烁到会话中.这样做是为了您可以在下一个请求期间方便地访问输入并重新填充用户尝试提交的表单。

要从先前的请求中检索闪烁的输入,请调用old 实例上的方法Illuminate\Http\Request.这old 方法将从中提取先前闪烁的输入数据session:

$title = $request->old('title');

Laravel 还提供了一个全局的old 帮手。如果您在刀片模板, 使用起来更方便old 重新填充表单的助手。如果给定字段不存在旧输入,null将返回:

<input type="text" name="title" value="{{ old('title') }}">

关于可选字段的注释

默认情况下,Laravel 包括TrimStringsConvertEmptyStringsToNull 应用程序的全局中间件堆栈中的中间件。这些中间件在堆栈中由App\Http\Kernel 班级。因此,您通常需要将“可选”请求字段标记为nullable 如果你不想让验证者考虑null 值无效。例如:

$request->validate([
    'title' => 'required|unique:posts|max:255',
    'body' => 'required',
    'publish_at' => 'nullable|date',
]);

在这个例子中,我们指定publish_at 字段可以是null 或有效的日期表示。如果nullable 修饰符未添加到规则定义中,验证器将考虑null 一个无效的日期。

验证错误响应格式

当您的应用程序抛出Illuminate\Validation\ValidationException 异常并且传入的 HTTP 请求需要 JSON 响应,Laravel 将自动为您格式化错误消息并返回一个422 Unprocessable Entity HTTP 响应。

下面,您可以查看验证错误的 JSON 响应格式示例。请注意,嵌套的错误键被扁平化为“点”符号格式:

{
    "message": "The team name must be a string. (and 4 more errors)",
    "errors": {
        "team_name": [
            "The team name must be a string.",
            "The team name must be at least 1 characters."
        ],
        "authorization.role": [
            "The selected authorization.role is invalid."
        ],
        "users.0.email": [
            "The users.0.email field is required."
        ],
        "users.2.email": [
            "The users.2.email must be a valid email address."
        ]
    }
}

表单请求验证

创建表单请求

对于更复杂的验证场景,您可能希望创建一个“表单请求”。表单请求是封装了自己的验证和授权逻辑的自定义请求类。要创建表单请求类,您可以使用make:request 工匠 CLI 命令:

php artisan make:request StorePostRequest

生成的表单请求类会放在app/Http/Requests 目录。如果该目录不存在,将在运行时创建make:request 命令。 Laravel 生成的每个表单请求都有两个方法:authorizerules.

正如您可能已经猜到的那样,authorize 方法负责确定当前经过身份验证的用户是否可以执行请求所表示的操作,而rules 方法返回应用于请求数据的验证规则:

/**
 * Get the validation rules that apply to the request.
 *
 * @return array<string, \Illuminate\Contracts\Validation\Rule|array|string>
 */
public function rules(): array
{
    return [
        'title' => 'required|unique:posts|max:255',
        'body' => 'required',
    ];
}

Note
您可以在rules 方法的签名。它们将通过 Laravel 自动解决服务容器.

那么,验证规则是如何评估的呢?您需要做的就是在您的控制器方法上对请求进行类型提示。在调用控制器方法之前验证传入的表单请求,这意味着您不需要使用任何验证逻辑来​​扰乱您的控制器:

/**
 * Store a new blog post.
 */
public function store(StorePostRequest $request): RedirectResponse
{
    // The incoming request is valid...

    // Retrieve the validated input data...
    $validated = $request->validated();

    // Retrieve a portion of the validated input data...
    $validated = $request->safe()->only(['name', 'email']);
    $validated = $request->safe()->except(['name', 'email']);

    // Store the blog post...

    return redirect('/posts');
}

如果验证失败,将生成重定向响应以将用户发送回他们之前的位置。错误也将闪现到会话中,以便它们可供显示。如果请求是 XHR 请求,将向用户返回带有 422 状态代码的 HTTP 响应,其中包括验证错误的 JSON 表示.

添加 After Hooks 到表单请求

如果您想向表单请求添加“之后”验证挂钩,您可以使用withValidator 方法。此方法接收完全构造的验证器,允许您在实际评估验证规则之前调用它的任何方法:

use Illuminate\Validation\Validator;

/**
 * Configure the validator instance.
 */
public function withValidator(Validator $validator): void
{
    $validator->after(function (Validator $validator) {
        if ($this->somethingElseIsInvalid()) {
            $validator->errors()->add('field', 'Something is wrong with this field!');
        }
    });
}

Stopping On First Validation Failure 属性

通过添加一个stopOnFirstFailure 将属性添加到您的请求类中,您可以通知验证器一旦发生单个验证失败,它应该停止验证所有属性:

/**
 * Indicates if the validator should stop on the first rule failure.
 *
 * @var bool
 */
protected $stopOnFirstFailure = true;

自定义重定向位置

如前所述,当表单请求验证失败时,将生成重定向响应以将用户发送回他们之前的位置。但是,您可以自由自定义此行为。为此,定义一个$redirect 您的表格请求中的属性:

/**
 * The URI that users should be redirected to if validation fails.
 *
 * @var string
 */
protected $redirect = '/dashboard';

或者,如果您想将用户重定向到命名路由,您可以定义一个$redirectRoute 财产代替:

/**
 * The route that users should be redirected to if validation fails.
 *
 * @var string
 */
protected $redirectRoute = 'dashboard';

授权表格请求

表单请求类还包含一个authorize 方法。在此方法中,您可以确定经过身份验证的用户是否确实有权更新给定资源。例如,您可以确定用户是否实际拥有他们尝试更新的博客评论。最有可能的是,您会与您的授权门和政策 在这个方法中:

use App\Models\Comment;

/**
 * Determine if the user is authorized to make this request.
 */
public function authorize(): bool
{
    $comment = Comment::find($this->route('comment'));

    return $comment && $this->user()->can('update', $comment);
}

因为所有的表单请求都扩展了 Laravel 请求类,我们可以使用user 访问当前经过身份验证的用户的方法。另外,请注意调用route 上面例子中的方法。此方法授予您访问在被调用的路由上定义的 URI 参数的权限,例如{comment}下例中的参数:

Route::post('/comment/{comment}');

因此,如果您的应用程序正在利用路由模型绑定,通过将已解析的模型作为请求的属性访问,您的代码可能会变得更加简洁:

return $this->user()->can('update', $this->comment);

如果authorize 方法返回false,将自动返回带有 403 状态代码的 HTTP 响应,并且您的控制器方法将不会执行。

如果您计划在应用程序的另一部分处理请求的授权逻辑,您可以简单地返回true 来自authorize 方法:

/**
 * Determine if the user is authorized to make this request.
 */
public function authorize(): bool
{
    return true;
}

Note
您可以在authorize 方法的签名。它们将通过 Laravel 自动解决服务容器.

自定义错误消息

您可以通过覆盖messages 方法。此方法应返回一组属性/规则对及其相应的错误消息:

/**
 * Get the error messages for the defined validation rules.
 *
 * @return array<string, string>
 */
public function messages(): array
{
    return [
        'title.required' => 'A title is required',
        'body.required' => 'A message is required',
    ];
}

自定义验证属性

Laravel 的许多内置验证规则错误消息都包含一个:attribute 占位符。如果你想:attribute 要替换为自定义属性名称的验证消息的占位符,您可以通过覆盖attributes 方法。此方法应返回一个属性/名称对数组:

/**
 * Get custom attributes for validator errors.
 *
 * @return array<string, string>
 */
public function attributes(): array
{
    return [
        'email' => 'email address',
    ];
}

准备输入以进行验证

如果您需要在应用验证规则之前准备或清理请求中的任何数据,您可以使用prepareForValidation 方法:

use Illuminate\Support\Str;

/**
 * Prepare the data for validation.
 */
protected function prepareForValidation(): void
{
    $this->merge([
        'slug' => Str::slug($this->slug),
    ]);
}

同样,如果您需要在验证完成后规范化任何请求数据,您可以使用passedValidation 方法:

use Illuminate\Support\Str;

/**
 * Handle a passed validation attempt.
 */
protected function passedValidation(): void
{
    $this->replace(['name' => 'Taylor']);
}

手动创建验证器

如果您不想使用validate 请求方法,您可以使用Validator facade.这make facade 上的方法生成一个新的验证器实例:

<?php

namespace App\Http\Controllers;

use App\Http\Controllers\Controller;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;

class PostController extends Controller
{
    /**
     * Store a new blog post.
     */
    public function store(Request $request): RedirectResponse
    {
        $validator = Validator::make($request->all(), [
            'title' => 'required|unique:posts|max:255',
            'body' => 'required',
        ]);

        if ($validator->fails()) {
            return redirect('post/create')
                        ->withErrors($validator)
                        ->withInput();
        }

        // Retrieve the validated input...
        $validated = $validator->validated();

        // Retrieve a portion of the validated input...
        $validated = $validator->safe()->only(['name', 'email']);
        $validated = $validator->safe()->except(['name', 'email']);

        // Store the blog post...

        return redirect('/posts');
    }
}

第一个参数传递给make 方法是正在验证的数据。第二个参数是应该应用于数据的验证规则数组。

在确定请求验证是否失败后,您可以使用withErrors 方法将错误消息闪烁到会话中。使用此方法时,$errors 变量将在重定向后自动与您的视图共享,使您可以轻松地将它们显示给用户。这withErrors 方法接受一个验证器,一个MessageBag, 或者一个 PHParray.

在第一次验证失败时停止

stopOnFirstFailure 方法将通知验证器,一旦发生单个验证失败,它应该停止验证所有属性:

if ($validator->stopOnFirstFailure()->fails()) {
    // ...
}

自动重定向

如果您想手动创建一个验证器实例,但仍然利用 HTTP 请求提供的自动重定向validate 方法,你可以调用validate 现有验证器实例上的方法。如果验证失败,用户将被自动重定向,或者在 XHR 请求的情况下,一个将返回 JSON 响应:

Validator::make($request->all(), [
    'title' => 'required|unique:posts|max:255',
    'body' => 'required',
])->validate();

您可以使用validateWithBag 方法将错误消息存储在命名错误包 如果验证失败:

Validator::make($request->all(), [
    'title' => 'required|unique:posts|max:255',
    'body' => 'required',
])->validateWithBag('post');

命名错误包

如果您在一个页面上有多个表单,您可能希望将MessageBag 包含验证错误,允许您检索特定表单的错误消息。为此,将名称作为第二个参数传递给withErrors:

return redirect('register')->withErrors($validator, 'login');

然后您可以访问指定的MessageBag 实例来自$errors 多变的:

{{ $errors->login->first('email') }}

自定义错误消息

如果需要,您可以提供验证器实例应该使用的自定义错误消息,而不是 Laravel 提供的默认错误消息。有几种方法可以指定自定义消息。首先,您可以将自定义消息作为第三个参数传递给Validator::make 方法:

$validator = Validator::make($input, $rules, $messages = [
    'required' => 'The :attribute field is required.',
]);

在这个例子中,:attribute 占位符将被验证字段的实际名称替换。您还可以在验证消息中使用其他占位符。例如:

$messages = [
    'same' => 'The :attribute and :other must match.',
    'size' => 'The :attribute must be exactly :size.',
    'between' => 'The :attribute value :input is not between :min - :max.',
    'in' => 'The :attribute must be one of the following types: :values',
];

为给定属性指定自定义消息

有时您可能希望仅为特定属性指定自定义错误消息。您可以使用“点”符号来这样做。首先指定属性的名称,然后是规则:

$messages = [
    'email.required' => 'We need to know your email address!',
];

指定自定义属性值

Laravel 的许多内置错误消息包括:attribute 被验证的字段或属性的名称替换的占位符。要自定义用于替换特定字段的这些占位符的值,您可以将自定义属性数组作为第四个参数传递给Validator::make方法:

$validator = Validator::make($input, $rules, $messages, [
    'email' => 'email address',
]);

验证后挂钩

您还可以附加要在验证完成后运行的回调。这使您可以轻松地执行进一步的验证,甚至可以将更多错误消息添加到消息集合中。要开始,请致电after 验证器实例上的方法:

use Illuminate\Support\Facades;
use Illuminate\Validation\Validator;

$validator = Facades\Validator::make(/* ... */);

$validator->after(function (Validator $validator) {
    if ($this->somethingElseIsInvalid()) {
        $validator->errors()->add(
            'field', 'Something is wrong with this field!'
        );
    }
});

if ($validator->fails()) {
    // ...
}

使用经过验证的输入

在使用表单请求或手动创建的验证器实例验证传入请求数据后,您可能希望检索实际经过验证的传入请求数据。这可以通过多种方式实现。首先,您可以致电validated 表单请求或验证器实例上的方法。此方法返回经过验证的数据数组:

$validated = $request->validated();

$validated = $validator->validated();

或者,您可以致电safe 表单请求或验证器实例上的方法。该方法返回一个实例Illuminate\Support\ValidatedInput.这个对象暴露only,except, 和all 检索已验证数据的子集或已验证数据的整个数组的方法:

$validated = $request->safe()->only(['name', 'email']);

$validated = $request->safe()->except(['name', 'email']);

$validated = $request->safe()->all();

除此之外Illuminate\Support\ValidatedInput 实例可以像数组一样被迭代和访问:

// Validated data may be iterated...
foreach ($request->safe() as $key => $value) {
    // ...
}

// Validated data may be accessed as an array...
$validated = $request->safe();

$email = $validated['email'];

如果您想向验证数据添加其他字段,您可以调用merge 方法:

$validated = $request->safe()->merge(['name' => 'Taylor Otwell']);

如果您想将经过验证的数据检索为collection 例如,您可以调用collect 方法:

$collection = $request->safe()->collect();

处理错误消息

调用后errors 上的方法Validator 例如,您将收到一个Illuminate\Support\MessageBag 实例,它有多种方便的方法来处理错误消息。这$errors 自动提供给所有视图的变量也是MessageBag 班级。

检索字段的第一条错误消息

要检索给定字段的第一条错误消息,请使用first 方法:

$errors = $validator->errors();

echo $errors->first('email');

检索字段的所有错误消息

如果您需要检索给定字段的所有消息的数组,请使用get 方法:

foreach ($errors->get('email') as $message) {
    // ...
}

如果您正在验证数组表单字段,您可以使用以下方法检索每个数组元素的所有消息* 特点:

foreach ($errors->get('attachments.*') as $message) {
    // ...
}

检索所有字段的所有错误消息

要检索所有字段的所有消息的数组,请使用all 方法:

foreach ($errors->all() as $message) {
    // ...
}

确定字段是否存在消息

has 方法可用于确定给定字段是否存在任何错误消息:

if ($errors->has('email')) {
    // ...
}

在语言文件中指定自定义消息

Laravel 的内置验证规则每个都有一条错误消息,位于您的应用程序的lang/en/validation.php 文件。在此文件中,您将找到每个验证规则的翻译条目。您可以根据应用程序的需要自由更改或修改这些消息。

此外,您可以将此文件复制到另一个语言目录,以将消息翻译为您的应用程序语言。要了解有关 Laravel 本地化的更多信息,请查看完整的本地化文档.

Warning 默认情况下,Laravel 应用程序框架不包括lang 目录。如果你想自定义 Laravel 的语言文件,你可以通过lang:publish 工匠命令。

特定属性的自定义消息

您可以在应用程序的验证语言文件中自定义用于指定属性和规则组合的错误消息。为此,请将您的消息自定义添加到custom 你的应用程序的数组lang/xx/validation.php 语言文件:

'custom' => [
    'email' => [
        'required' => 'We need to know your email address!',
        'max' => 'Your email address is too long!'
    ],
],

在语言文件中指定属性

Laravel 的许多内置错误消息包括:attribute 被验证的字段或属性的名称替换的占位符。如果你想:attribute 要用自定义值替换的验证消息部分,您可以在attributes 你的数组lang/xx/validation.php 语言文件:

'attributes' => [
    'email' => 'email address',
],

Warning 默认情况下,Laravel 应用程序框架不包括lang 目录。如果你想自定义 Laravel 的语言文件,你可以通过lang:publish 工匠命令。

在语言文件中指定值

Laravel 的一些内置验证规则错误消息包含:value 替换为请求属性的当前值的占位符。但是,您可能偶尔需要:value 验证消息的一部分将替换为值的自定义表示。例如,考虑以下规则,该规则指定如果payment_type的值为cc:

Validator::make($request->all(), [
    'credit_card_number' => 'required_if:payment_type,cc'
]);

如果此验证规则失败,它将产生以下错误消息:

The credit card number field is required when payment type is cc.

而不是显示cc 作为付款类型值,您可以在您的lang/xx/validation.php 通过定义一个语言文件values 大批:

'values' => [
    'payment_type' => [
        'cc' => 'credit card'
    ],
],

Warning 默认情况下,Laravel 应用程序框架不包括lang 目录。如果你想自定义 Laravel 的语言文件,你可以通过lang:publish 工匠命令。

定义此值后,验证规则将产生以下错误消息:

The credit card number field is required when payment type is credit card.

可用的验证规则

以下是所有可用验证规则及其功能的列表:

accepted

验证中的字段必须是"yes","on",1, 或者true.这对于验证“服务条款”接受或类似字段很有用。

accepted_if:anotherfield,value,...

验证中的字段必须是"yes","on",1, 或者true 如果验证中的另一个字段等于指定值。这对于验证“服务条款”接受或类似字段很有用。

active_url

验证字段必须具有有效的 A 或 AAAA 记录dns_get_record PHP函数。提供的 URL 的主机名是使用parse_url 传递给之前的 PHP 函数dns_get_record.

after:date

验证字段必须是给定日期之后的值。日期将被传递到strtotime PHP函数才能转换为有效的DateTime 实例:

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

而不是传递要评估的日期字符串strtotime,您可以指定另一个字段来与日期进行比较:

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

after_or_equal:date

验证字段必须是给定日期之后或等于给定日期的值。有关详细信息,请参阅after 规则。

alpha

被验证的字段必须完全是 Unicode 字母字符包含在\p{L}\p{M}.

要将此验证规则限制为 ASCII 范围内的字符 (a-zA-Z), 你可以提供ascii 验证规则的选项:

'username' => 'alpha:ascii',

alpha_dash

验证字段必须完全是 Unicode 字母数字字符,包含在\p{L},\p{M},\p{N}, 以及 ASCII 破折号 (-) 和 ASCII 下划线 (_).

要将此验证规则限制为 ASCII 范围内的字符 (a-zA-Z), 你可以提供ascii 验证规则的选项:

'username' => 'alpha_dash:ascii',

alpha_num

验证字段必须完全是 Unicode 字母数字字符,包含在\p{L},\p{M}, 和\p{N}.

要将此验证规则限制为 ASCII 范围内的字符 (a-zA-Z), 你可以提供ascii 验证规则的选项:

'username' => 'alpha_num:ascii',

array

验证字段必须是 PHParray.

当附加值提供给array 规则,输入数组中的每个键都必须出现在提供给规则的值列表中。在下面的示例中,admin 输入数组中的键无效,因为它不包含在提供给array 规则:

use Illuminate\Support\Facades\Validator;

$input = [
    'user' => [
        'name' => 'Taylor Otwell',
        'username' => 'taylorotwell',
        'admin' => true,
    ],
];

Validator::make($input, [
    'user' => 'array:name,username',
]);

通常,您应该始终指定允许出现在数组中的数组键。

ascii

验证字段必须完全是 7 位 ASCII 字符。

bail

在第一次验证失败后停止为该字段运行验证规则。

虽然bail 规则只会在遇到验证失败时停止验证特定字段,stopOnFirstFailure 方法将通知验证器,一旦发生单个验证失败,它应该停止验证所有属性:

if ($validator->stopOnFirstFailure()->fails()) {
    // ...
}

before:date

验证字段必须是给定日期之前的值。日期将被传递到 PHPstrtotime函数,以便转换为有效的DateTime 实例。此外,像after 规则,验证中的另一个字段的名称可以作为值提供date.

before_or_equal:date

验证字段必须是给定日期之前或等于给定日期的值。日期将被传递到 PHPstrtotime 函数,以便转换为有效的DateTime 实例。此外,像after 规则,验证中的另一个字段的名称可以作为值提供date.

between:min,max

验证字段的大小必须介于给定的minmax (包括的)。字符串、数字、数组和文件的计算方式与size 规则。

boolean

验证中的字段必须能够转换为布尔值。接受的输入是true,false,1,0,"1", 和"0".

confirmed

正在验证的字段必须具有匹配字段{field}_confirmation.例如,如果正在验证的字段是password, 一个匹配password_confirmation 字段必须存在于输入中。

current_password

验证中的字段必须与经过身份验证的用户的密码相匹配。您可以指定一个鉴权守卫 使用规则的第一个参数:

'password' => 'current_password:api'

date

验证字段必须是有效的、非相对日期strtotime PHP函数。

date_equals:date

验证字段必须等于给定日期。日期将被传递到 PHPstrtotime 函数,以便转换为有效的DateTime 实例。

date_format:format,...

验证中的字段必须匹配给定的字段之一formats.你应该使用either date 或者date_format 在验证一个字段时,不是两者。此验证规则支持 PHP 支持的所有格式DateTime 班级。

decimal:min,max

验证字段必须是数字,并且必须包含指定的小数位数:

// Must have exactly two decimal places (9.99)...
'price' => 'decimal:2'

// Must have between 2 and 4 decimal places...
'price' => 'decimal:2,4'

declined

验证中的字段必须是"no","off",0, 或者false.

declined_if:anotherfield,value,...

验证中的字段必须是"no","off",0, 或者false 如果验证中的另一个字段等于指定值。

different:field

正在验证的字段必须具有不同的值field.

digits:value

验证中的整数必须具有精确的长度value.

digits_between:min,max

整数验证的长度必须介于给定的minmax.

dimensions

正在验证的文件必须是满足规则参数指定的尺寸约束的图像:

'avatar' => 'dimensions:min_width=100,min_height=200'

可用的约束是:min_width,max_width,min_height,max_height,width,height,ratio.

Aratio 约束应表示为宽度除以高度。这可以通过像这样的分数来指定3/2 或者像一个浮动1.5:

'avatar' => 'dimensions:ratio=3/2'

由于此规则需要多个参数,因此您可以使用Rule::dimensions 流畅构建规则的方法:

use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;

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

distinct

验证数组时,验证字段不能有任何重复值:

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

默认情况下,Distinct 使用松散变量比较。要使用严格比较,您可以添加strict 验证规则定义的参数:

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

您可以添加ignore_case 到验证规则的参数,使规则忽略大小写差异:

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

doesnt_start_with:foo,bar,...

验证中的字段不得以给定值之一开头。

doesnt_end_with:foo,bar,...

验证中的字段不得以给定值之一结尾。

email

验证字段的格式必须为电子邮件地址。此验证规则利用egulias/email-validator 用于验证电子邮件地址的包。默认情况下,RFCValidation 已应用验证器,但您也可以应用其他验证样式:

'email' => 'email:rfc,dns'

上面的示例将应用RFCValidationDNSCheckValidation 验证。以下是您可以应用的验证样式的完整列表:

  • rfc:RFCValidation
  • strict:NoRFCWarningsValidation
  • dns:DNSCheckValidation
  • spoof:SpoofCheckValidation
  • filter:FilterEmailValidation
  • filter_unicode:FilterEmailValidation::unicode()

filter 验证器,它使用 PHP 的filter_var 函数,随 Laravel 一起提供,并且是 Laravel 5.8 版本之前 Laravel 的默认电子邮件验证行为。

Warning
dnsspoof 验证器需要 PHPintl 扩大。

ends_with:foo,bar,...

验证中的字段必须以给定值之一结尾。

enum

Enum rule 是一个基于类的规则,用于验证被验证的字段是否包含有效的枚举值。这Enum 规则接受枚举的名称作为其唯一的构造函数参数:

use App\Enums\ServerStatus;
use Illuminate\Validation\Rules\Enum;

$request->validate([
    'status' => [new Enum(ServerStatus::class)],
]);

Warning
枚举仅适用于 PHP 8.1+。

exclude

正在验证的字段将从返回的请求数据中排除validatevalidated 方法。

exclude_if:anotherfield,value

正在验证的字段将从返回的请求数据中排除validatevalidated 方法如果anotherfield 字段等于value.

如果需要复杂的条件排除逻辑,您可以使用Rule::excludeIf方法。此方法接受布尔值或闭包。当给出闭包时,闭包应该返回true 或者false 指示是否应排除正在验证的字段:

use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;

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

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

exclude_unless:anotherfield,value

正在验证的字段将从返回的请求数据中排除validatevalidated 方法除非anotherfield的字段等于value.如果valuenull (exclude_unless:name,null), 验证字段将被排除,除非比较字段是null 或者请求数据中缺少比较字段。

exclude_with:anotherfield

正在验证的字段将从返回的请求数据中排除validatevalidated 方法如果anotherfield 字段存在。

exclude_without:anotherfield

正在验证的字段将从返回的请求数据中排除validatevalidated 方法如果anotherfield 字段不存在。

exists:table,column

验证字段必须存在于给定的数据库表中。

存在规则的基本用法

'state' => 'exists:states'

如果column 未指定选项,将使用字段名称。因此,在这种情况下,该规则将验证states 数据库表包含一条记录state 与请求匹配的列值state 属性值。

指定自定义列名称

您可以明确指定验证规则应使用的数据库列名,方法是将其放在数据库表名之后:

'state' => 'exists:states,abbreviation'

有时,您可能需要指定一个特定的数据库连接以用于exists 询问。您可以通过将连接名称添加到表名称来完成此操作:

'email' => 'exists:connection.staff,email'

您可以指定用于确定表名的 Eloquent 模型,而不是直接指定表名:

'user_id' => 'exists:App\Models\User,id'

如果你想自定义验证规则执行的查询,你可以使用Rule 类来流畅地定义规则。在此示例中,我们还将验证规则指定为数组而不是使用| 分隔它们的字符:

use Illuminate\Database\Query\Builder;
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;

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

您可以显式指定应由exists 规则生成的Rule::exists 通过提供列名作为第二个参数的方法exists 方法:

'state' => Rule::exists('states', 'abbreviation'),

file

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

filled

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

gt:field

验证字段必须大于给定的field.这两个字段必须是同一类型。字符串、数字、数组和文件使用与size 规则。

gte:field

验证的字段必须大于或等于给定的field.这两个字段必须是同一类型。字符串、数字、数组和文件使用与size 规则。

image

验证的文件必须是图像(jpg、jpeg、png、bmp、gif、svg 或 webp)。

in:foo,bar,...

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

use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;

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

当。。。的时候in 规则与array 规则,输入数组中的每个值都必须出现在提供给in 规则。在下面的示例中,LAS 输入数组中的机场代码无效,因为它不包含在提供给in 规则:

use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;

$input = [
    'airports' => ['NYC', 'LAS'],
];

Validator::make($input, [
    'airports' => [
        'required',
        'array',
    ],
    'airports.*' => Rule::in(['NYC', 'LIT']),
]);

in_array:anotherfield.*

正在验证的字段必须存在于anotherfield的价值观。

integer

验证字段必须是整数。

Warning
此验证规则不验证输入是否为“整数”变量类型,仅验证输入是否为 PHP 接受的类型FILTER_VALIDATE_INT 规则。如果您需要将输入验证为数字,请结合使用此规则numeric 验证规则.

ip

验证字段必须是 IP 地址。

ipv4

验证字段必须是 IPv4 地址。

ipv6

验证字段必须是 IPv6 地址。

json

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

lt:field

正在验证的字段必须小于给定的field.这两个字段必须是同一类型。字符串、数字、数组和文件使用与size 规则。

lte:field

验证中的字段必须小于或等于给定的field.这两个字段必须是同一类型。字符串、数字、数组和文件使用与size规则。

lowercase

验证字段必须是小写。

mac_address

验证字段必须是 MAC 地址。

max:value

验证字段必须小于或等于最大值value.字符串、数字、数组和文件的计算方式与size 规则。

max_digits:value

验证中的整数的最大长度必须为value.

mimetypes:text/plain,...

正在验证的文件必须匹配给定的 MIME 类型之一:

'video' => 'mimetypes:video/avi,video/mpeg,video/quicktime'

要确定上传文件的 MIME 类型,将读取文件的内容,框架将尝试猜测 MIME 类型,这可能与客户端提供的 MIME 类型不同。

mimes:foo,bar,...

正在验证的文件必须具有与列出的扩展名之一相对应的 MIME 类型。

MIME 规则的基本用法

'photo' => 'mimes:jpg,bmp,png'

尽管您只需要指定扩展名,但此规则实际上通过读取文件的内容并猜测其 MIME 类型来验证文件的 MIME 类型。可以在以下位置找到 MIME 类型及其相应扩展名的完整列表:

https://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types

min:value

正在验证的字段必须至少有value.字符串、数字、数组和文件的计算方式与size 规则。

min_digits:value

验证中的整数的最小长度必须为value.

multiple_of:value

验证字段必须是以下的倍数value.

missing

正在验证的字段不得出现在输入数据中。

missing_if:anotherfield,value,...

如果anotherfield 字段等于任何value.

missing_unless:anotherfield,value

验证中的字段不得存在,除非anotherfield 字段等于任何value.

missing_with:foo,bar,...

验证中的字段不得存在除非 存在任何其他指定字段。

missing_with_all:foo,bar,...

验证中的字段不得存在除非 所有其他指定的字段都存在。

not_in:foo,bar,...

验证中的字段不得包含在给定的值列表中。这Rule::notIn 方法可用于流畅地构建规则:

use Illuminate\Validation\Rule;

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

not_regex:pattern

验证中的字段不得与给定的正则表达式匹配。

在内部,此规则使用 PHPpreg_match 功能。指定的模式应遵循preg_match 因此也包括有效的分隔符。例如:'email' => 'not_regex:/^.+$/i'.

Warning
当使用regex /not_regex 模式,可能需要使用数组而不是使用来指定验证规则| 定界符,尤其是当正则表达式包含| 特点。

nullable

正在验证的字段可能是null.

numeric

验证中的字段必须是numeric.

password

验证中的字段必须与经过身份验证的用户的密码相匹配。

Warning
此规则已重命名为current_password 打算在 Laravel 9 中删除它。请使用当前密码 代替统治。

present

验证字段必须存在于输入数据中。

prohibited

验证中的字段必须缺失或为空。如果一个字段满足以下条件之一,则该字段为“空”:

  • 价值是null.
  • 该值为空字符串。
  • 该值为空数组或为空Countable 目的。
  • 该值为空路径的上传文件。

prohibited_if:anotherfield,value,...

如果验证中的字段必须缺失或为空anotherfield 字段等于任何value.如果一个字段满足以下条件之一,则该字段为“空”:

  • 价值是null.
  • 该值为空字符串。
  • 该值为空数组或为空Countable 目的。
  • 该值为空路径的上传文件。

如果需要复杂的条件禁止逻辑,您可以使用Rule::prohibitedIf 方法。此方法接受布尔值或闭包。当给出闭包时,闭包应该返回true 或者false 指示是否应禁止验证中的字段:

use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;

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

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

prohibited_unless:anotherfield,value,...

验证中的字段必须缺失或为空,除非anotherfield 字段等于任何value.如果一个字段满足以下条件之一,则该字段为“空”:

  • 价值是null.
  • 该值为空字符串。
  • 该值为空数组或为空Countable 目的。
  • 该值为空路径的上传文件。

prohibits:anotherfield,...

如果正在验证的字段没有丢失或为空,则所有字段在anotherfield 必须缺失或为空。如果一个字段满足以下条件之一,则该字段为“空”:

  • 价值是null.
  • 该值为空字符串。
  • 该值为空数组或为空Countable 目的。
  • 该值为空路径的上传文件。

regex:pattern

验证中的字段必须匹配给定的正则表达式。

在内部,此规则使用 PHPpreg_match 功能。指定的模式应遵循preg_match 因此也包括有效的分隔符。例如:'email' => 'regex:/^.+@.+$/i'.

Warning
当使用regex /not_regex 模式,可能需要在数组中指定规则而不是使用| 定界符,尤其是当正则表达式包含| 特点。

required

验证字段必须存在于输入数据中且不能为空。如果一个字段满足以下条件之一,则该字段为“空”:

  • 价值是null.
  • 该值为空字符串。
  • 该值为空数组或为空Countable 目的。
  • 该值是一个没有路径的上传文件。

required_if:anotherfield,value,...

如果anotherfield 字段等于任何value.

如果您想为required_if 规则,你可以使用Rule::requiredIf 方法。此方法接受布尔值或闭包。当通过闭包时,闭包应该返回true 或者false 指示是否需要验证字段:

use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;

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

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

required_unless:anotherfield,value,...

验证中的字段必须存在且不能为空,除非anotherfield 字段等于任何value.这也意味着anotherfield 必须出现在请求数据中,除非valuenull.如果valuenull (required_unless:name,null), 验证字段将是必需的,除非比较字段是null 或者请求数据中缺少比较字段。

required_with:foo,bar,...

验证字段必须存在且不能为空除非 任何其他指定字段都存在且不为空。

required_with_all:foo,bar,...

验证字段必须存在且不能为空除非 所有其他指定字段都存在且不为空。

required_without:foo,bar,...

验证字段必须存在且不能为空只有当 任何其他指定字段为空或不存在。

required_without_all:foo,bar,...

验证字段必须存在且不能为空只有当 所有其他指定的字段都是空的或不存在。

required_array_keys:foo,bar,...

验证的字段必须是一个数组,并且必须至少包含指定的键。

same:field

给定的field 必须匹配验证中的字段。

size:value

验证字段的大小必须与给定的匹配value.对于字符串数据,value 对应字符数。对于数字数据,value 对应于给定的整数值(该属性还必须具有numeric 或者integer 规则)。对于数组,size 对应于count 的阵列。对于文件,size 对应于以千字节为单位的文件大小。让我们看一些例子:

// Validate that a string is exactly 12 characters long...
'title' => 'size:12';

// Validate that a provided integer equals 10...
'seats' => 'integer|size:10';

// Validate that an array has exactly 5 elements...
'tags' => 'array|size:5';

// Validate that an uploaded file is exactly 512 kilobytes...
'image' => 'file|size:512';

starts_with:foo,bar,...

验证中的字段必须以给定值之一开头。

string

验证字段必须是字符串。如果你想让这个领域也成为null,你应该分配nullable 统治领域。

timezone

验证字段必须是有效的时区标识符timezone_identifiers_list PHP函数。

unique:table,column

正在验证的字段不得存在于给定的数据库表中。

指定自定义表/列名称:

您可以指定用于确定表名的 Eloquent 模型,而不是直接指定表名:

'email' => 'unique:App\Models\User,email_address'

column 选项可用于指定字段对应的数据库列。如果column 未指定选项,将使用验证中的字段名称。

'email' => 'unique:users,email_address'

指定自定义数据库连接

有时,您可能需要为验证器进行的数据库查询设置自定义连接。为此,您可以将连接名称添加到表名称之前:

'email' => 'unique:connection.users,email_address'

强制唯一规则忽略给定 ID:

有时,您可能希望在唯一验证期间忽略给定的 ID。例如,考虑一个包含用户姓名、电子邮件地址和位置的“更新配置文件”屏幕。您可能想要验证电子邮件地址是否唯一。但是,如果用户只更改名称字段而不更改电子邮件字段,您不希望抛出验证错误,因为用户已经是相关电子邮件地址的所有者。

为了指示验证器忽略用户的 ID,我们将使用Rule 类来流畅地定义规则。在此示例中,我们还将验证规则指定为数组而不是使用|分隔规则的字符:

use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;

Validator::make($data, [
    'email' => [
        'required',
        Rule::unique('users')->ignore($user->id),
    ],
]);

Warning
你永远不应该将任何用户控制的请求输入传递​​到ignore 方法。相反,您应该只传递系统生成的唯一 ID,例如来自 Eloquent 模型实例的自动递增 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(fn (Builder $query) => $query->where('account_id', 1))

uppercase

验证字段必须大写。

url

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

ulid

正在验证的字段必须是有效的普遍唯一的字典排序标识符 (ULID)。

uuid

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

有条件地添加规则

当字段具有特定值时跳过验证

如果另一个字段具有给定值,您有时可能希望不验证给定字段。您可以使用exclude_if 验证规则。在这个例子中,appointment_datedoctor_name 如果has_appointment 字段的值为false:

use Illuminate\Support\Facades\Validator;

$validator = Validator::make($data, [
    'has_appointment' => 'required|boolean',
    'appointment_date' => 'exclude_if:has_appointment,false|required|date',
    'doctor_name' => 'exclude_if:has_appointment,false|required|string',
]);

或者,您可以使用exclude_unless 除非另一个字段具有给定值,否则不验证给定字段的规则:

$validator = Validator::make($data, [
    'has_appointment' => 'required|boolean',
    'appointment_date' => 'exclude_unless:has_appointment,true|required|date',
    'doctor_name' => 'exclude_unless:has_appointment,true|required|string',
]);

存在时验证

在某些情况下,您可能希望对字段运行验证检查only 如果该字段存在于正在验证的数据中。要快速完成此操作,请添加sometimes 规则到您的规则列表:

$v = Validator::make($data, [
    'email' => 'sometimes|required|email',
]);

在上面的例子中,email 字段只有在存在于$data 大批。

Note
如果您尝试验证应始终存在但可能为空的字段,请查看关于可选字段的注释.

复杂的条件验证

有时您可能希望添加基于更复杂的条件逻辑的验证规则。例如,您可能希望仅当另一个字段的值大于 100 时才需要给定字段。或者,您可能需要两个字段只有在另一个字段存在时才具有给定值。添加这些验证规则并不一定很痛苦。首先,创建一个Validator 与你的实例静态规则 永远不会改变:

use Illuminate\Support\Facades\Validator;

$validator = Validator::make($request->all(), [
    'email' => 'required|email',
    'games' => 'required|numeric',
]);

假设我们的 Web 应用程序适用于游戏收藏家。如果游戏收藏家在我们的应用程序中注册并且他们拥有 100 多款游戏,我们希望他们解释为什么他们拥有这么多游戏。例如,他们可能经营一家游戏转售店,或者他们可能只是喜欢收集游戏。要有条件地添加此要求,我们可以使用sometimes 上的方法Validator 实例。

use Illuminate\Support\Fluent;

$validator->sometimes('reason', 'required|max:500', function (Fluent $input) {
    return $input->games >= 100;
});

第一个参数传递给sometimes method 是我们有条件验证的字段的名称。第二个参数是我们要添加的规则列表。如果闭包作为第三个参数返回true, 将添加规则。这种方法使得构建复杂的条件验证变得轻而易举。您甚至可以同时为多个字段添加条件验证:

$validator->sometimes(['reason', 'cost'], 'required', function (Fluent $input) {
    return $input->games >= 100;
});

Note
$input 传递给闭包的参数将是Illuminate\Support\Fluent 并可用于访问您的输入和正在验证的文件。

复杂条件数组验证

有时您可能希望根据同一嵌套数组中您不知道其索引的另一个字段来验证一个字段。在这些情况下,您可以允许闭包接收第二个参数,该参数将是正在验证的数组中的当前单个项:

$input = [
    'channels' => [
        [
            'type' => 'email',
            'address' => 'abigail@example.com',
        ],
        [
            'type' => 'url',
            'address' => 'https://example.com',
        ],
    ],
];

$validator->sometimes('channels.*.address', 'email', function (Fluent $input, Fluent $item) {
    return $item->type === 'email';
});

$validator->sometimes('channels.*.address', 'url', function (Fluent $input, Fluent $item) {
    return $item->type !== 'email';
});

$input 传递给闭包的参数,$item 参数是一个实例Illuminate\Support\Fluent 当属性数据是数组时;否则,它是一个字符串。

验证数组

正如在array 验证规则文档, 这array 规则接受允许的数组键列表。如果数组中存在任何其他键,验证将失败:

use Illuminate\Support\Facades\Validator;

$input = [
    'user' => [
        'name' => 'Taylor Otwell',
        'username' => 'taylorotwell',
        'admin' => true,
    ],
];

Validator::make($input, [
    'user' => 'array:username,locale',
]);

通常,您应该始终指定允许出现在数组中的数组键。否则,验证者的validatevalidated 方法将返回所有经过验证的数据,包括数组及其所有键,即使这些键未被其他嵌套数组验证规则验证。

验证嵌套数组输入

验证基于嵌套数组的表单输入字段并不一定很痛苦。您可以使用“点符号”来验证数组中的属性。例如,如果传入的 HTTP 请求包含photos[profile] 字段,您可以像这样验证它:

use Illuminate\Support\Facades\Validator;

$validator = Validator::make($request->all(), [
    'photos.profile' => 'required|image',
]);

您还可以验证数组的每个元素。例如,要验证给定数组输入字段中的每封电子邮件都是唯一的,您可以执行以下操作:

$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 email address',
    ]
],

访问嵌套数组数据

有时,在将验证规则分配给属性时,您可能需要访问给定嵌套数组元素的值。您可以使用Rule::forEach 方法。这forEach 方法接受一个闭包,该闭包将在验证时为数组属性的每次迭代调用,并将接收属性的值和显式的、完全扩展的属性名称。闭包应返回一组规则以分配给数组元素:

use App\Rules\HasPermission;
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;

$validator = Validator::make($request->all(), [
    'companies.*.id' => Rule::forEach(function (string|null $value, string $attribute) {
        return [
            Rule::exists(Company::class, 'id'),
            new HasPermission('manage-company', $value),
        ];
    }),
]);

错误信息索引和位置

验证数组时,您可能希望在应用程序显示的错误消息中引用验证失败的特定项的索引或位置。为此,您可以包括:index (从开始0) 和:position (从开始1) 中的占位符自定义验证消息:

use Illuminate\Support\Facades\Validator;

$input = [
    'photos' => [
        [
            'name' => 'BeachVacation.jpg',
            'description' => 'A photo of my beach vacation!',
        ],
        [
            'name' => 'GrandCanyon.jpg',
            'description' => '',
        ],
    ],
];

Validator::validate($input, [
    'photos.*.description' => 'required',
], [
    'photos.*.description.required' => 'Please describe photo #:position.',
]);

在上面的示例中,验证将失败,用户将看到以下错误“请描述照片#2。”

验证文件

Laravel 提供了多种验证规则,可用于验证上传的文件,例如mimes,image,min, 和max.虽然您可以在验证文件时自由地单独指定这些规则,但 Laravel 还提供了一个流畅的文件验证规则构建器,您可能会发现它很方便:

use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rules\File;

Validator::validate($input, [
    'attachment' => [
        'required',
        File::types(['mp3', 'wav'])
            ->min(1024)
            ->max(12 * 1024),
    ],
]);

如果您的应用程序接受用户上传的图片,您可以使用File 规则的image 构造方法来指示上传的文件应该是一个图像。除此之外dimensions 规则可用于限制图像的尺寸:

use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rules\File;

Validator::validate($input, [
    'photo' => [
        'required',
        File::image()
            ->min(1024)
            ->max(12 * 1024)
            ->dimensions(Rule::dimensions()->maxWidth(1000)->maxHeight(500)),
    ],
]);

Note
有关验证图像尺寸的更多信息,请参见维度规则文档.

文件类型

即使您只需要在调用时指定扩展名types 方法,该方法实际上通过读取文件的内容并猜测其 MIME 类型来验证文件的 MIME 类型。可以在以下位置找到 MIME 类型及其相应扩展名的完整列表:

https://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types

验证密码

为确保密码具有足够的复杂性,您可以使用 Laravel 的Password 规则对象:

use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rules\Password;

$validator = Validator::make($request->all(), [
    'password' => ['required', 'confirmed', Password::min(8)],
]);

Password 规则对象允许您轻松地为您的应用程序自定义密码复杂性要求,例如指定密码至少需要一个字母、数字、符号或混合大小写的字符:

// Require at least 8 characters...
Password::min(8)

// Require at least one letter...
Password::min(8)->letters()

// Require at least one uppercase and one lowercase letter...
Password::min(8)->mixedCase()

// Require at least one number...
Password::min(8)->numbers()

// Require at least one symbol...
Password::min(8)->symbols()

此外,您可以使用uncompromised 方法:

Password::min(8)->uncompromised()

在内部,Password 规则对象使用k-Anonymity 模型来确定密码是否已通过haveibeenpwned.com 在不牺牲用户隐私或安全的情况下提供服务。

默认情况下,如果密码在数据泄露中至少出现一次,则将被视为泄露。您可以使用的第一个参数自定义此阈值uncompromised 方法:

// Ensure the password appears less than 3 times in the same data leak...
Password::min(8)->uncompromised(3);

当然,您可以链接上面示例中的所有方法:

Password::min(8)
    ->letters()
    ->mixedCase()
    ->numbers()
    ->symbols()
    ->uncompromised()

定义默认密码规则

您可能会发现在应用程序的单个位置指定密码的默认验证规则很方便。您可以使用Password::defaults方法,它接受一个闭包。给的闭包defaults 方法应返回密码规则的默认配置。通常,defaults 规则应该在boot 您的应用程序服务提供商之一的方法:

use Illuminate\Validation\Rules\Password;

/**
 * Bootstrap any application services.
 */
public function boot(): void
{
    Password::defaults(function () {
        $rule = Password::min(8);

        return $this->app->isProduction()
                    ? $rule->mixedCase()->uncompromised()
                    : $rule;
    });
}

然后,当您想将默认规则应用于正在验证的特定密码时,您可以调用defaults 没有参数的方法:

'password' => ['required', Password::defaults()],

有时,您可能希望将其他验证规则附加到默认密码验证规则。您可以使用rules 方法来完成这个:

use App\Rules\ZxcvbnRule;

Password::defaults(function () {
    $rule = Password::min(8)->rules([new ZxcvbnRule]);

    // ...
});

自定义验证规则

使用规则对象

Laravel 提供了各种有用的验证规则;但是,您可能希望指定一些您自己的。注册自定义验证规则的一种方法是使用规则对象。要生成新的规则对象,您可以使用make:rule 工匠命令。让我们使用这个命令来生成一个规则来验证字符串是否为大写。 Laravel 会将新规则放在app/Rules 目录。如果这个目录不存在,Laravel 会在你执行 Artisan 命令来创建你的规则时创建它:

php artisan make:rule Uppercase

创建规则后,我们就可以定义其行为了。规则对象包含一个方法:validate.此方法接收属性名称、它的值以及应在验证错误消息失败时调用的回调:

<?php

namespace App\Rules;

use Closure;
use Illuminate\Contracts\Validation\ValidationRule;

class Uppercase implements ValidationRule
{
    /**
     * Run the validation rule.
     */
    public function validate(string $attribute, mixed $value, Closure $fail): void
    {
        if (strtoupper($value) !== $value) {
            $fail('The :attribute must be uppercase.');
        }
    }
}

定义规则后,您可以通过将规则对象的实例与其他验证规则一起传递来将其附加到验证器:

use App\Rules\Uppercase;

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

翻译验证消息

而不是向$fail 闭包,你也可以提供一个翻译字符串键 并指示 Laravel 翻译错误信息:

if (strtoupper($value) !== $value) {
    $fail('validation.uppercase')->translate();
}

如有必要,您可以提供占位符替换和首选语言作为translate 方法:

$fail('validation.location')->translate([
    'value' => $this->value,
], 'fr')

访问附加数据

如果您的自定义验证规则类需要访问所有其他正在验证的数据,您的规则类可以实现Illuminate\Contracts\Validation\DataAwareRule 界面。这个接口要求你的类定义一个setData 方法。 Laravel 将自动调用此方法(在验证进行之前),所有数据都在验证中:

<?php

namespace App\Rules;

use Illuminate\Contracts\Validation\DataAwareRule;
use Illuminate\Contracts\Validation\ValidationRule;

class Uppercase implements DataAwareRule, ValidationRule
{
    /**
     * All of the data under validation.
     *
     * @var array<string, mixed>
     */
    protected $data = [];

    // ...

    /**
     * Set the data under validation.
     *
     * @param  array<string, mixed>  $data
     */
    public function setData(array $data): static
    {
        $this->data = $data;

        return $this;
    }
}

或者,如果您的验证规则需要访问执行验证的验证器实例,您可以实现ValidatorAwareRule 界面:

<?php

namespace App\Rules;

use Illuminate\Contracts\Validation\ValidationRule;
use Illuminate\Contracts\Validation\ValidatorAwareRule;
use Illuminate\Validation\Validator;

class Uppercase implements ValidationRule, ValidatorAwareRule
{
    /**
     * The validator instance.
     *
     * @var \Illuminate\Validation\Validator
     */
    protected $validator;

    // ...

    /**
     * Set the current validator.
     */
    public function setValidator(Validator $validator): static
    {
        $this->validator = $validator;

        return $this;
    }
}

使用闭包

如果您在整个应用程序中只需要一次自定义规则的功能,则可以使用闭包而不是规则对象。闭包接收属性名、属性值和一个$fail 验证失败时应调用的回调:

use Illuminate\Support\Facades\Validator;

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

隐式规则

默认情况下,当要验证的属性不存在或包含空字符串时,不会运行正常的验证规则,包括自定义规则。例如,unique 规则不会针对空字符串运行:

use Illuminate\Support\Facades\Validator;

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

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

Validator::make($input, $rules)->passes(); // true

对于即使属性为空也能运行的自定义规则,规则必须暗示该属性是必需的。要快速生成新的隐式规则对象,您可以使用make:rule 工匠命令与--implicit 选项:

php artisan make:rule Uppercase --implicit

Warning
只有“隐式”规则implies 该属性是必需的。它是否实际上使缺失或空属性无效取决于您。

豫ICP备18041297号-2