跳至内容

验证

介绍

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

Laravel 包含各种便捷的验证规则,您可以将其应用于数据,甚至可以验证给定数据库表中的值是否唯一。我们将详细介绍每条验证规则,以便您熟悉 Laravel 的所有验证功能。

验证快速入门

为了了解 Laravel 强大的验证功能,我们来看一个完整的示例,它验证表单并将错误信息显示给用户。通过阅读这个概述,你将能够很好地理解如何使用 Laravel 验证传入的请求数据:

定义路线

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

1use App\Http\Controllers\PostController;
2 
3Route::get('/post/create', [PostController::class, 'create']);
4Route::post('/post', [PostController::class, 'store']);

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

创建控制器

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

1<?php
2 
3namespace App\Http\Controllers;
4 
5use Illuminate\Http\RedirectResponse;
6use Illuminate\Http\Request;
7use Illuminate\View\View;
8 
9class PostController extends Controller
10{
11 /**
12 * Show the form to create a new blog post.
13 */
14 public function create(): View
15 {
16 return view('post.create');
17 }
18 
19 /**
20 * Store a new blog post.
21 */
22 public function store(Request $request): RedirectResponse
23 {
24 // Validate and store the blog post...
25 
26 $post = /** ... */
27 
28 return to_route('post.show', ['post' => $post->id]);
29 }
30}

编写验证逻辑

现在,我们准备在store方法中填充逻辑来验证新的博客文章。为此,我们将使用对象validate提供的方法Illuminate\Http\Request。如果验证规则通过,代码将继续正常执行;但是,如果验证失败,Illuminate\Validation\ValidationException则会引发异常,并自动将正确的错误响应发送回用户。

如果在传统 HTTP 请求中验证失败,则会生成重定向到先前 URL 的响应。如果传入的请求是 XHR 请求,则会返回包含验证错误消息的 JSON 响应。

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

1/**
2 * Store a new blog post.
3 */
4public function store(Request $request): RedirectResponse
5{
6 $validated = $request->validate([
7 'title' => 'required|unique:posts|max:255',
8 'body' => 'required',
9 ]);
10 
11 // The blog post is valid...
12 
13 return redirect('/posts');
14}

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

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

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

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

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

第一次验证失败时停止

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

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

在此示例中,如果属性unique上的规则title失败,max则不会检查该规则。规则将按照其分配的顺序进行验证。

关于嵌套属性的注释

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

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

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

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

显示验证错误

那么,如果传入的请求字段未通过给定的验证规则怎么办?如前所述,Laravel 会自动将用户重定向回其先前的位置。此外,所有验证错误和请求输入都将自动刷新到 session 中

中间件组提供的中间件会将变量$errors共享给应用程序的所有视图。应用此中间件后,变量将始终在视图中可用,让您可以方便地假设该变量始终已定义并且可以安全使用。该变量将是 的一个实例。有关使用此对象的更多信息,请参阅其文档Illuminate\View\Middleware\ShareErrorsFromSessionweb$errors$errors$errorsIlluminate\Support\MessageBag

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

1<!-- /resources/views/post/create.blade.php -->
2 
3<h1>Create Post</h1>
4 
5@if ($errors->any())
6 <div class="alert alert-danger">
7 <ul>
8 @foreach ($errors->all() as $error)
9 <li>{{ $error }}</li>
10 @endforeach
11 </ul>
12 </div>
13@endif
14 
15<!-- Create Post Form -->

自定义错误消息

Laravel 的内置验证规则每个都有一个错误消息,位于应用程序的lang/en/validation.php文件中。如果您的应用程序没有目录lang,您可以使用 Artisan 命令指示 Laravel 创建它lang:publish

在该文件中lang/en/validation.php,您将找到每个验证规则的翻译条目。您可以根据应用程序的需要随意更改或修改这些消息。

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

默认情况下,Laravel 应用程序骨架不包含该lang目录。如果您想自定义 Laravel 的语言文件,可以通过lang:publishArtisan 命令发布它们。

XHR 请求和验证

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

指令@error

你可以使用@error Blade指令快速判断指定属性是否存在验证错误信息。在@error指令中,你可以 echo$message变量来显示错误信息:

1<!-- /resources/views/post/create.blade.php -->
2 
3<label for="title">Post Title</label>
4 
5<input
6 id="title"
7 type="text"
8 name="title"
9 class="@error('title') is-invalid @enderror"
10/>
11 
12@error('title')
13 <div class="alert alert-danger">{{ $message }}</div>
14@enderror

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

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

重新填充表格

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

要检索上一次请求中闪现的输入,请old在 的实例上调用 的方法Illuminate\Http\Request。该方法将从会话old中提取先前闪现的输入数据

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

Laravel 还提供了一个全局Helpers。如果您要在Blade 模板old中显示旧输入,则使用该Helpers重新填充表单会更方便。如果给定字段不存在旧输入,则将返回:oldnull

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

关于可选字段的说明

默认情况下,Laravel 会在应用程序的全局中间件栈中包含TrimStringsConvertEmptyStringsToNull中间件。因此,你通常需要将请求字段标记为“可选”,nullable以免验证器将null值视为无效。例如:

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

在此示例中,我们指定该publish_at字段可以是null或 有效的日期表示。如果nullable规则定义中未添加修饰符,则验证器将视为null无效日期。

验证错误响应格式

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

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

1{
2 "message": "The team name must be a string. (and 4 more errors)",
3 "errors": {
4 "team_name": [
5 "The team name must be a string.",
6 "The team name must be at least 1 characters."
7 ],
8 "authorization.role": [
9 "The selected authorization.role is invalid."
10 ],
11 "users.0.email": [
12 "The users.0.email field is required."
13 ],
14 "users.2.email": [
15 "The users.2.email must be a valid email address."
16 ]
17 }
18}

表单请求验证

创建表单请求

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

1php artisan make:request StorePostRequest

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

您可能已经猜到了,该authorize方法负责确定当前经过身份验证的用户是否可以执行请求所代表的操作,同时该rules方法返响应适用于请求数据的验证规则:

1/**
2 * Get the validation rules that apply to the request.
3 *
4 * @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
5 */
6public function rules(): array
7{
8 return [
9 'title' => 'required|unique:posts|max:255',
10 'body' => 'required',
11 ];
12}

你可以在方法签名中键入任何所需的依赖项。它们将通过 Laravel服务容器rules自动解析

那么,验证规则是如何评估的呢?您只需在控制器方法上对请求进行类型Prompts即可。传入的表单请求会在调用控制器方法之前进行验证,这意味着您无需在控制器中添加任何验证逻辑:

1/**
2 * Store a new blog post.
3 */
4public function store(StorePostRequest $request): RedirectResponse
5{
6 // The incoming request is valid...
7 
8 // Retrieve the validated input data...
9 $validated = $request->validated();
10 
11 // Retrieve a portion of the validated input data...
12 $validated = $request->safe()->only(['name', 'email']);
13 $validated = $request->safe()->except(['name', 'email']);
14 
15 // Store the blog post...
16 
17 return redirect('/posts');
18}

如果验证失败,系统会生成一个重定向响应,将用户送回之前的位置。错误信息也会被闪现到会话中,以便用户查看。如果请求是 XHR 请求,则会返回一个包含 422 状态码的 HTTP 响应,其中包含验证错误的 JSON 格式

需要为 Inertia 驱动的 Laravel 前端添加实时表单请求验证吗?请查看Laravel Precognition

执行附加验证

有时,您需要在初始验证完成后执行其他验证。您可以使用表单请求的after方法来实现。

after方法应返回一个可调用函数或闭包数组,这些函数将在验证完成后被调用。给定的可调用函数将接收一个Illuminate\Validation\Validator实例,以便你在必要时抛出额外的错误消息:

1use Illuminate\Validation\Validator;
2 
3/**
4 * Get the "after" validation callables for the request.
5 */
6public function after(): array
7{
8 return [
9 function (Validator $validator) {
10 if ($this->somethingElseIsInvalid()) {
11 $validator->errors()->add(
12 'field',
13 'Something is wrong with this field!'
14 );
15 }
16 }
17 ];
18}

如上所述,该after方法返回的数组也可能包含可调用类。__invoke这些类的方法将接收一个Illuminate\Validation\Validator实例:

1use App\Validation\ValidateShippingTime;
2use App\Validation\ValidateUserStatus;
3use Illuminate\Validation\Validator;
4 
5/**
6 * Get the "after" validation callables for the request.
7 */
8public function after(): array
9{
10 return [
11 new ValidateUserStatus,
12 new ValidateShippingTime,
13 function (Validator $validator) {
14 //
15 }
16 ];
17}

第一次验证失败时停止

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

1/**
2 * Indicates if the validator should stop on the first rule failure.
3 *
4 * @var bool
5 */
6protected $stopOnFirstFailure = true;

自定义重定向位置

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

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

或者,如果您想将用户重定向到命名路线,您可以定义一个$redirectRoute属性:

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

授权表单请求

表单请求类还包含一个authorize方法。在此方法中,您可以判断已验证的用户是否确实拥有更新给定资源的权限。例如,您可以判断用户是否真正拥有他们尝试更新的博客评论。您很可能会在该方法中与授权门和策略进行交互:

1use App\Models\Comment;
2 
3/**
4 * Determine if the user is authorized to make this request.
5 */
6public function authorize(): bool
7{
8 $comment = Comment::find($this->route('comment'));
9 
10 return $comment && $this->user()->can('update', $comment);
11}

由于所有表单请求都扩展了 Laravel 基类,因此我们可以使用该user方法来访问当前已验证的用户。另请注意上例中对该方法的调用route。此方法授予您访问被调用路由上定义的 URI 参数的权限,例如{comment}以下示例中的参数:

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

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

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

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

如果您计划在应用程序的另一部分处理请求的授权逻辑,则可以authorize完全删除该方法,或者简单地返回true

1/**
2 * Determine if the user is authorized to make this request.
3 */
4public function authorize(): bool
5{
6 return true;
7}

你可以在方法签名中键入任何所需的依赖项。它们将通过 Laravel服务容器authorize自动解析

自定义错误消息

你可以通过重写该方法来自定义表单请求的错误消息messages。该方法应返回一个包含属性/规则对及其对应错误消息的数组:

1/**
2 * Get the error messages for the defined validation rules.
3 *
4 * @return array<string, string>
5 */
6public function messages(): array
7{
8 return [
9 'title.required' => 'A title is required',
10 'body.required' => 'A message is required',
11 ];
12}

自定义验证属性

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

1/**
2 * Get custom attributes for validator errors.
3 *
4 * @return array<string, string>
5 */
6public function attributes(): array
7{
8 return [
9 'email' => 'email address',
10 ];
11}

准备验证输入

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

1use Illuminate\Support\Str;
2 
3/**
4 * Prepare the data for validation.
5 */
6protected function prepareForValidation(): void
7{
8 $this->merge([
9 'slug' => Str::slug($this->slug),
10 ]);
11}

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

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

手动创建验证器

如果你不想validate在请求中使用该方法,你可以使用Validator Facade手动创建一个验证器实例。Facademake上的方法会生成一个新的验证器实例:

1<?php
2 
3namespace App\Http\Controllers;
4 
5use Illuminate\Http\RedirectResponse;
6use Illuminate\Http\Request;
7use Illuminate\Support\Facades\Validator;
8 
9class PostController extends Controller
10{
11 /**
12 * Store a new blog post.
13 */
14 public function store(Request $request): RedirectResponse
15 {
16 $validator = Validator::make($request->all(), [
17 'title' => 'required|unique:posts|max:255',
18 'body' => 'required',
19 ]);
20 
21 if ($validator->fails()) {
22 return redirect('/post/create')
23 ->withErrors($validator)
24 ->withInput();
25 }
26 
27 // Retrieve the validated input...
28 $validated = $validator->validated();
29 
30 // Retrieve a portion of the validated input...
31 $validated = $validator->safe()->only(['name', 'email']);
32 $validated = $validator->safe()->except(['name', 'email']);
33 
34 // Store the blog post...
35 
36 return redirect('/posts');
37 }
38}

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

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

第一次验证失败时停止

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

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

自动重定向

如果您想手动创建验证器实例,但仍想利用 HTTP 请求validate方法提供的自动重定向功能,则可以validate在现有验证器实例上调用该方法。如果验证失败,用户将自动重定向;或者,如果是 XHR 请求,则返回 JSON 响应

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

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

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

命名错误包

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

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

MessageBag然后您可以从变量访问命名实例$errors

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

自定义错误消息

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

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

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

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

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

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

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

指定自定义属性值

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

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

执行附加验证

有时,您需要在初始验证完成后执行额外的验证。您可以使用验证器的after方法来实现。该after方法接受一个闭包或一个可调用函数数组,这些函数将在验证完成后调用。给定的可调用函数将接收一个Illuminate\Validation\Validator实例,以便您在必要时抛出额外的错误消息:

1use Illuminate\Support\Facades\Validator;
2 
3$validator = Validator::make(/* ... */);
4 
5$validator->after(function ($validator) {
6 if ($this->somethingElseIsInvalid()) {
7 $validator->errors()->add(
8 'field', 'Something is wrong with this field!'
9 );
10 }
11});
12 
13if ($validator->fails()) {
14 // ...
15}

如上所述,该after方法还接受一个可调用数组,如果您的“验证后”逻辑封装在可调用类中,这将特别方便,可调用类将Illuminate\Validation\Validator通过其__invoke方法接收一个实例:

1use App\Validation\ValidateShippingTime;
2use App\Validation\ValidateUserStatus;
3 
4$validator->after([
5 new ValidateUserStatus,
6 new ValidateShippingTime,
7 function ($validator) {
8 // ...
9 },
10]);

使用已验证的输入

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

1$validated = $request->validated();
2 
3$validated = $validator->validated();

safe或者,您也可以在表单请求或验证器实例上调用该方法。此方法返回 的一个实例Illuminate\Support\ValidatedInput。该对象公开onlyexceptall方法来检索已验证数据的子集或整个已验证数据数组:

1$validated = $request->safe()->only(['name', 'email']);
2 
3$validated = $request->safe()->except(['name', 'email']);
4 
5$validated = $request->safe()->all();

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

1// Validated data may be iterated...
2foreach ($request->safe() as $key => $value) {
3 // ...
4}
5 
6// Validated data may be accessed as an array...
7$validated = $request->safe();
8 
9$email = $validated['email'];

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

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

如果您希望将验证的数据作为集合实例检索,您可以调用该collect方法:

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

处理错误消息

在实例上调用该errors方法后Validator,您将收到一个Illuminate\Support\MessageBag实例,该实例具有多种用于处理错误消息的便捷方法。$errors自动提供给所有视图的变量也是该类的一个实例MessageBag

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

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

1$errors = $validator->errors();
2 
3echo $errors->first('email');

检索字段的所有错误消息

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

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

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

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

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

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

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

确定字段是否存在消息

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

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

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

Laravel 的内置验证规则每个都有一个错误消息,位于应用程序的lang/en/validation.php文件中。如果您的应用程序没有目录lang,您可以使用 Artisan 命令指示 Laravel 创建它lang:publish

在该文件中lang/en/validation.php,您将找到每个验证规则的翻译条目。您可以根据应用程序的需要随意更改或修改这些消息。

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

默认情况下,Laravel 应用程序骨架不包含该lang目录。如果您想自定义 Laravel 的语言文件,可以通过lang:publishArtisan 命令发布它们。

特定属性的自定义消息

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

1'custom' => [
2 'email' => [
3 'required' => 'We need to know your email address!',
4 'max' => 'Your email address is too long!'
5 ],
6],

在语言文件中指定属性

Laravel 的许多内置错误消息都包含一个:attribute占位符,该占位符会被替换为验证字段或属性的名称。如果您希望将验证消息的这一部分替换为自定义值,则可以在语言文件的数组:attribute中指定自定义属性名称attributeslang/xx/validation.php

1'attributes' => [
2 'email' => 'email address',
3],

默认情况下,Laravel 应用程序骨架不包含该lang目录。如果您想自定义 Laravel 的语言文件,可以通过lang:publishArtisan 命令发布它们。

在语言文件中指定值

Laravel 的一些内置验证规则错误消息包含一个:value占位符,该占位符会被替换为请求属性的当前值。但是,有时你可能需要将验证消息的这一部分替换为自定义的值表示形式。例如,考虑以下规则,该规则规定,如果的值为 ,:value则需要输入信用卡号payment_typecc

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

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

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

您可以通过定义数组cc在语言文件中指定更加用户友好的值表示,而不是显示为付款类型值lang/xx/validation.phpvalues

1'values' => [
2 'payment_type' => [
3 'cc' => 'credit card'
4 ],
5],

默认情况下,Laravel 应用程序骨架不包含该lang目录。如果您想自定义 Laravel 的语言文件,可以通过lang:publishArtisan 命令发布它们。

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

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

可用的验证规则

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

布尔值

字符串

数字

数组

日期

文件

数据库

实用工具

公认

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

accepted_if:另一个字段,值,...

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

active_url

根据dns_get_recordPHP 函数,验证字段必须具有有效的 A 或 AAAA 记录。所提供 URL 的主机名parse_url在传递给 之前,会使用 PHP 函数提取dns_get_record

日期之后

验证字段的值必须是指定日期之后的值。该日期将被传入strtotimePHP 函数,以便转换为有效DateTime实例:

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

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

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

为了方便起见,可以使用流畅的date规则构建器来构建基于日期的规则:

1use Illuminate\Validation\Rule;
2 
3'start_date' => [
4 'required',
5 Rule::date()->after(today()->addDays(7)),
6],

afterToday方法todayOrAfter可以分别用于流畅地表达日期必须在今天之后或或今天或之后:

1'start_date' => [
2 'required',
3 Rule::date()->afterToday(),
4],

after_or_equal:日期

验证字段的值必须晚于或等于指定日期。更多信息,请参阅after规则。

为了方便起见,可以使用流畅的date规则构建器来构建基于日期的规则:

1use Illuminate\Validation\Rule;
2 
3'start_date' => [
4 'required',
5 Rule::date()->afterOrEqual(today()->addDays(7)),
6],

任意

验证规则Rule::anyOf允许您指定验证字段必须满足任何给定的验证规则集。例如,以下规则将验证该username字段是电子邮件地址还是长度至少为 6 个字符的字母数字字符串(包括短划线):

1use Illuminate\Validation\Rule;
2 
3'username' => [
4 'required',
5 Rule::anyOf([
6 ['string', 'email'],
7 ['string', 'alpha_dash', 'min:6'],
8 ]),
9],

阿尔法

验证字段必须完全由\p{L}\p{M}中包含的 Unicode 字母字符组成。

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

1'username' => 'alpha:ascii',

alpha_dash

验证字段必须完全由\p{L}\p{M}\p{N}以及 ASCII 破折号 ( -) 和 ASCII 下划线 ( _) 中包含的 Unicode 字母数字字符组成。

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

1'username' => 'alpha_dash:ascii',

alpha_num

验证字段必须完全由\p{L}\p{M}\p{N}中包含的 Unicode 字母数字字符组成。

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

1'username' => 'alpha_num:ascii',

大批

验证下的字段必须是 PHP array

当向规则提供其他值时array,输入数组中的每个键都必须存在于提供给规则的值列表中。在以下示例中,admin输入数组中的键无效,因为它不包含在提供给array规则的值列表中:

1use Illuminate\Support\Facades\Validator;
2 
3$input = [
4 'user' => [
5 'name' => 'Taylor Otwell',
6 'username' => 'taylorotwell',
7 'admin' => true,
8 ],
9];
10 
11Validator::make($input, [
12 'user' => 'array:name,username',
13]);

一般来说,您应该始终指定允许存在于数组中的数组键。

ASCII

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

保释

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

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

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

之前:日期

验证字段的值必须早于给定日期。该日期将被传入 PHPstrtotime函数,以便转换为有效DateTime实例。此外,与after规则类似,验证中的另一个字段的名称可以作为 的值date

为了方便起见,也可以使用流畅的date规则构建器来构建基于日期的规则:

1use Illuminate\Validation\Rule;
2 
3'start_date' => [
4 'required',
5 Rule::date()->before(today()->subDays(7)),
6],

beforeToday方法todayOrBefore可以分别用于流畅地表达日期必须在今天之前或或今天或之前:

1'start_date' => [
2 'required',
3 Rule::date()->beforeToday(),
4],

之前或等于:日期

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

为了方便起见,也可以使用流畅的date规则构建器来构建基于日期的规则:

1use Illuminate\Validation\Rule;
2 
3'start_date' => [
4 'required',
5 Rule::date()->beforeOrEqual(today()->subDays(7)),
6],

介于:最小值最大值之间

待验证字段的大小必须介于给定的最小值最大值之间(含)。字符串、数值、数组和文件的评估方式与大小规则相同

布尔值

验证字段必须能够转换为布尔值。可接受的输入包括truefalse10"1""0"

确认的

验证字段必须具有匹配字段{field}_confirmation。例如,如果验证字段为,则输入中必须存在password匹配字段。password_confirmation

您还可以传递自定义确认字段名称。例如,confirmed:repeat_username期望该字段repeat_username与验证字段匹配。

包含:foobar,...

验证字段必须是包含所有给定参数值的数组。由于此规则通常需要使用implode数组,因此Rule::contains可以使用以下方法来流畅地构建规则:

1use Illuminate\Support\Facades\Validator;
2use Illuminate\Validation\Rule;
3 
4Validator::make($data, [
5 'roles' => [
6 'required',
7 'array',
8 Rule::contains(['admin', 'editor']),
9 ],
10]);

当前密码

验证字段必须与已认证用户的密码匹配。你可以使用规则的第一个参数指定身份验证保护:

1'password' => 'current_password:api'

日期

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

date_equals:日期

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

date_format:格式,...

验证字段必须符合给定格式之一。验证字段时,应使用 date,而不是同时使用两者。此验证规则支持 PHP DateTime类支持的所有格式。date_format

为了方便起见,可以使用流畅的date规则构建器来构建基于日期的规则:

1use Illuminate\Validation\Rule;
2 
3'start_date' => [
4 'required',
5 Rule::date()->format('Y-m-d'),
6],

小数:最小值最大值

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

1// Must have exactly two decimal places (9.99)...
2'price' => 'decimal:2'
3 
4// Must have between 2 and 4 decimal places...
5'price' => 'decimal:2,4'

拒绝

验证的字段必须是"no""off"0"0"false"false"

descended_if:另一个字段,值,...

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

不同:字段

验证下的字段必须具有与字段不同的值。

数字:

验证的整数必须具有精确的的长度。

数字之间:最小值最大值

整数验证的长度必须介于给定的最小值最大值之间。

方面

验证的文件必须是符合规则参数指定的尺寸约束的图像:

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

可用的约束有:min_widthmax_widthmin_heightmax_heightwidthheightratio

比例约束应表示为宽度除以高度。可以使用分数3/2或浮点数来指定,例如1.5

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

Rule::dimensions由于该规则需要几个参数,因此使用该方法来流畅地构建规则通常更方便:

1use Illuminate\Support\Facades\Validator;
2use Illuminate\Validation\Rule;
3 
4Validator::make($data, [
5 'avatar' => [
6 'required',
7 Rule::dimensions()
8 ->maxWidth(1000)
9 ->maxHeight(500)
10 ->ratio(3 / 2),
11 ],
12]);

清楚的

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

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

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

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

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

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

doesnt_start_with:foobar,...

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

doesnt_end_with:foobar,...

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

电子邮件

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

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

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

  • rfcRFCValidation- 根据支持的 RFC验证电子邮件地址。
  • strictNoRFCWarningsValidation- 根据支持的 RFC验证电子邮件,当发现警告时(例如尾随句点和多个连续句点)则失败。
  • dnsDNSCheckValidation- 确保电子邮件地址的域名具有有效的 MX 记录。
  • spoof: SpoofCheckValidation- 确保电子邮件地址不包含同形异义词或欺骗性的 Unicode 字符。
  • filter: FilterEmailValidation- 根据 PHP 的filter_var功能确保电子邮件地址有效。
  • filter_unicode: FilterEmailValidation::unicode()- 确保电子邮件地址根据 PHP 的filter_var功能有效,允许使用一些 Unicode 字符。

为了方便起见,可以使用流畅的规则构建器来构建电子邮件验证规则:

1use Illuminate\Validation\Rule;
2 
3$request->validate([
4 'email' => [
5 'required',
6 Rule::email()
7 ->rfcCompliant(strict: false)
8 ->validateMxRecord()
9 ->preventSpoofing()
10 ],
11]);

dns和验证spoof需要 PHPintl扩展。

结尾为:foobar,...

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

枚举

Enum规则是一个基于类的规则,用于验证待验证字段是否包含有效的枚举值。该Enum规则接受枚举的名称作为其唯一的构造函数参数。当验证原始值时,应向规则提供一个支持的枚举Enum

1use App\Enums\ServerStatus;
2use Illuminate\Validation\Rule;
3 
4$request->validate([
5 'status' => [Rule::enum(ServerStatus::class)],
6]);

规则和方法Enum用于限制哪些枚举情况应被视为有效:onlyexcept

1Rule::enum(ServerStatus::class)
2 ->only([ServerStatus::Pending, ServerStatus::Active]);
3 
4Rule::enum(ServerStatus::class)
5 ->except([ServerStatus::Pending, ServerStatus::Active]);

when方法可用于有条件地修改Enum规则:

1use Illuminate\Support\Facades\Auth;
2use Illuminate\Validation\Rule;
3 
4Rule::enum(ServerStatus::class)
5 ->when(
6 Auth::user()->isAdmin(),
7 fn ($rule) => $rule->only(...),
8 fn ($rule) => $rule->only(...),
9 );

排除

验证下的字段将被排除在validatevalidated方法返回的请求数据之外。

exclude_if:另一个字段

如果anotherfield字段等于value,则验证下的字段将从validate和方法返回的请求数据中排除validated

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

1use Illuminate\Support\Facades\Validator;
2use Illuminate\Validation\Rule;
3 
4Validator::make($request->all(), [
5 'role_id' => Rule::excludeIf($request->user()->is_admin),
6]);
7 
8Validator::make($request->all(), [
9 'role_id' => Rule::excludeIf(fn () => $request->user()->is_admin),
10]);

exclude_unless:另一个字段

除非anotherfield的字段等于value ,否则验证中的字段将被排除在validatevalidated方法返回的请求数据之外。如果value( ) ,则验证中的字段将被排除,除非比较字段为或请求数据中缺少比较字段。nullexclude_unless:name,nullnull

exclude_with:另一个字段

如果存在anotherfield字段,则验证下的字段将从validate和方法返回的请求数据中排除。validated

exclude_without:另一个字段

如果anotherfield字段不存在,则验证下的字段将从validate和方法返回的请求数据中排除。validated

存在:

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

Exists 规则的基本用法

1'state' => 'exists:states'

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

指定自定义列名

您可以通过将数据库列名放在数据库表名之后来明确指定验证规则应该使用的数据库列名:

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

有时,你可能需要指定用于exists查询的特定数据库连接。你可以通过将连接名称添加到表名前面来实现:

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

除了直接指定表名之外,您还可以指定用于确定表名的 Eloquent 模型:

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

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

1use Illuminate\Database\Query\Builder;
2use Illuminate\Support\Facades\Validator;
3use Illuminate\Validation\Rule;
4 
5Validator::make($data, [
6 'email' => [
7 'required',
8 Rule::exists('staff')->where(function (Builder $query) {
9 $query->where('account_id', 1);
10 }),
11 ],
12]);

您可以通过将列名作为该方法的第二个参数来明确指定exists该方法生成的规则应使用的数据库列名Rule::existsexists

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

有时,你可能希望验证数据库中是否存在一个值数组。你可以将exists数组规则添加到要验证的字段来实现:

1'states' => ['array', Rule::exists('states', 'abbreviation')],

当这两个规则都分配给一个字段时,Laravel 将自动构建一个查询来确定所有给定的值是否存在于指定的表中。

扩展:foobar,...

验证的文件必须具有与列出的扩展名之一相对应的用户分配的扩展名:

1'photo' => ['required', 'extensions:jpg,png'],

您不应该仅依赖用户指定的扩展名来验证文件。此规则通常应始终与MIMEMIME 类型规则结合使用。

文件

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

已填满

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

gt:字段

验证的字段必须大于给定的字段。这两个字段必须属于同一类型。字符串、数值、数组和文件使用与size规则相同的约定进行评估。

gte:字段

验证的字段必须大于或等于给定的字段。这两个字段必须属于同一类型。字符串、数值、数组和文件使用与size规则相同的约定进行评估。

十六进制颜色

验证字段必须包含十六进制格式的有效颜色值。

图像

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

默认情况下,由于可能存在 XSS 漏洞,图像规则不允许 SVG 文件。如果您需要允许 SVG 文件,可以allow_svgimage规则提供指令 ( image:allow_svg)。

在:foobar,...

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

1use Illuminate\Support\Facades\Validator;
2use Illuminate\Validation\Rule;
3 
4Validator::make($data, [
5 'zones' => [
6 'required',
7 Rule::in(['first-zone', 'second-zone']),
8 ],
9]);

in规则与规则组合使用时array,输入数组中的每个值都必须存在于提供给in规则的值列表中。在以下示例中,LAS输入数组中的机场代码无效,因为它不包含在提供给规则的机场列表中in

1use Illuminate\Support\Facades\Validator;
2use Illuminate\Validation\Rule;
3 
4$input = [
5 'airports' => ['NYC', 'LAS'],
6];
7 
8Validator::make($input, [
9 'airports' => [
10 'required',
11 'array',
12 ],
13 'airports.*' => Rule::in(['NYC', 'LIT']),
14]);

in_array:另一个字段.*

验证下的字段必须存在于anotherfield的值中。

in_array_keys:.*

验证字段必须是一个数组,并且至少有一个给定作为数组中的键:

1'config' => 'array|in_array_keys:timezone'

整数

验证的字段必须是整数。

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

ip

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

IPv4

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

IPv6

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

json

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

lt:字段

验证的字段必须小于给定的字段。这两个字段必须属于同一类型。字符串、数值、数组和文件使用与size规则相同的约定进行评估。

lte:字段

验证的字段必须小于或等于给定的字段。这两个字段必须属于同一类型。字符串、数值、数组和文件使用与size规则相同的约定进行评估。

小写

验证的字段必须是小写。

列表

验证字段必须是列表类型的数组。如果数组的键由从 0 到 的连续数字组成,则该数组被视为列表count($array) - 1

mac_地址

验证的字段必须是 MAC 地址。

最大值:

验证字段必须小于或等于最大值。字符串、数值、数组和文件的评估方式与大小规则相同

max_digits:

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

模仿类型:text/plain,...

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

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

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

哑剧:foobar,...

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

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

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

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

MIME 类型和扩展

此验证规则不会验证 MIME 类型与用户分配给文件的扩展名之间的一致性。例如,mimes:png即使文件名为 ,该验证规则也会将包含有效 PNG 内容的文件视为有效的 PNG 图像photo.txt。如果您想验证用户分配给文件的扩展名,可以使用扩展名规则。

最小值:

验证字段必须具有最小值。字符串、数字、数组和文件的评估方式与大小规则相同

min_digits:

验证的整数必须具有的最小长度。

multiple_of:

验证下的字段必须是的倍数。

丢失的

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

missing_if:另一个字段,...

如果anotherfield字段等于任何值,则验证下的字段一定不存在

missing_unless:另一个字段

除非anotherfield字段等于任何,否则验证下的字段不得存在

missing_with:foobar,...

仅当存在任何其他指定字段时,验证下的字段才不能存在。

missing_with_all:foobar,...

仅当所有其他指定字段都存在时,验证下的字段才不能存在。

不在:foobar,...

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

1use Illuminate\Validation\Rule;
2 
3Validator::make($data, [
4 'toppings' => [
5 'required',
6 Rule::notIn(['sprinkles', 'cherries']),
7 ],
8]);

not_regex:模式

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

此规则内部使用 PHPpreg_match函数。指定的模式应遵循 所要求的相同格式preg_match,因此也包含有效的分隔符。例如:'email' => 'not_regex:/^.+$/i'

当使用regex/not_regex模式时,可能需要使用数组而不是使用|分隔符来指定验证规则,特别是当正则表达式包含|字符时。

可空

正在验证的字段可能是null

数字

验证的字段必须是数字

展示

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

present_if:另一个字段,...

如果anotherfield字段等于任何值,则验证下的字段必须存在

present_unless: anotherfield

除非anotherfield字段等于任何,否则验证下的字段必须存在

present_with:foobar,...

仅当存在任何其他指定字段时,验证下的字段才必须存在。

present_with_all: foo , bar ,...

仅当所有其他指定字段都存在时,验证下的字段才必须存在。

禁止

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

  • 值为null
  • 该值为空字符串。
  • 该值是一个空数组或空Countable对象。
  • 该值是一个已上传的文件,路径为空。

禁止条件:另一个字段,...

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

  • 值为null
  • 该值为空字符串。
  • 该值是一个空数组或空Countable对象。
  • 该值是一个已上传的文件,路径为空。

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

1use Illuminate\Support\Facades\Validator;
2use Illuminate\Validation\Rule;
3 
4Validator::make($request->all(), [
5 'role_id' => Rule::prohibitedIf($request->user()->is_admin),
6]);
7 
8Validator::make($request->all(), [
9 'role_id' => Rule::prohibitedIf(fn () => $request->user()->is_admin),
10]);

禁止接受:另一个字段,...

如果anotherfield字段等于"yes""on"1"1"true或,则验证下的字段必须缺失或为空"true"

禁止_如果_declined:另一个字段,...

如果anotherfield字段等于"no""off"0"0"false或,则验证下的字段必须缺失或为空"false"

禁止_除非:另一个字段,...

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

  • 值为null
  • 该值为空字符串。
  • 该值是一个空数组或空Countable对象。
  • 该值是一个已上传的文件,路径为空。

禁止:anotherfield,...

如果验证的字段没有缺失或为空,则其他字段中的所有字段都必须缺失或为空。如果字段满足以下条件之一,则为“空”:

  • 值为null
  • 该值为空字符串。
  • 该值是一个空数组或空Countable对象。
  • 该值是一个已上传的文件,路径为空。

正则表达式:模式

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

此规则内部使用 PHPpreg_match函数。指定的模式应遵循 所要求的相同格式preg_match,因此也包含有效的分隔符。例如:'email' => 'regex:/^.+@.+$/i'

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

必需的

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

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

required_if:另一个字段,...

如果anotherfield字段等于任何值,则验证下的字段必须存在且不能为空

如果您想为规则构建更复杂的条件required_if,可以使用该Rule::requiredIf方法。此方法接受布尔值或闭包。当传递闭包时,闭包应该返回true或 ,false以指示验证字段是否为必填项:

1use Illuminate\Support\Facades\Validator;
2use Illuminate\Validation\Rule;
3 
4Validator::make($request->all(), [
5 'role_id' => Rule::requiredIf($request->user()->is_admin),
6]);
7 
8Validator::make($request->all(), [
9 'role_id' => Rule::requiredIf(fn () => $request->user()->is_admin),
10]);

如果接受则需要:另一个字段,...

如果anotherfield字段等于"yes""on"1"1"true"true"则验证下的字段必须存在且不能为空。

如果拒绝则需要:另一个字段,...

如果anotherfield字段等于"no""off"0"0"false"false"则验证下的字段必须存在且不能为空。

除非必需:另一个字段,...

除非anotherfield字段等于任何,否则验证字段必须存在且不能为空。这也意味着,除非值为,否则anotherfield必须存在于请求数据中。如果值为( ) ,验证字段为必填字段,除非比较字段为或请求数据中缺少比较字段。nullnullrequired_unless:name,nullnull

必需:foobar,...

仅当任何其他指定字段存在且不为空时,验证下的字段才必须存在且不为空。

必需的:foobar,...

仅当所有其他指定字段都存在且不为空时,验证下的字段才必须存在且不为空。

必需的没有:foobar,...

仅当任何其他指定的字段为空或不存在时,验证下的字段才必须存在且不能为空。

必需但不全部:foobar,...

仅当所有其他指定字段为空或不存在时,验证下的字段才必须存在且不能为空。

必需数组键:foobar、...

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

相同:字段

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

大小:

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

1// Validate that a string is exactly 12 characters long...
2'title' => 'size:12';
3 
4// Validate that a provided integer equals 10...
5'seats' => 'integer|size:10';
6 
7// Validate that an array has exactly 5 elements...
8'tags' => 'array|size:5';
9 
10// Validate that an uploaded file is exactly 512 kilobytes...
11'image' => 'file|size:512';

开始于:foobar,...

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

细绳

验证的字段必须是字符串。如果您希望该字段也为字符串null,则需要nullable为该字段指定规则。

时区

根据该方法,验证下的字段必须是有效的时区标识符DateTimeZone::listIdentifiers

该方法接受的DateTimeZone::listIdentifiers参数也可以提供给此验证规则:

1'timezone' => 'required|timezone:all';
2 
3'timezone' => 'required|timezone:Africa';
4 
5'timezone' => 'required|timezone:per_country,US';

唯一:

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

指定自定义表/列名称:

除了直接指定表名之外,您还可以指定用于确定表名的 Eloquent 模型:

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

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

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

指定自定义数据库连接

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

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

强制执行唯一规则以忽略给定的 ID:

有时,您可能希望在唯一性验证期间忽略给定的 ID。例如,假设有一个“更新个人资料”屏幕,其中包含用户的姓名、电子邮件地址和位置。您可能希望验证电子邮件地址是否唯一。但是,如果用户只更改了姓名字段而没有更改电子邮件字段,您肯定不希望抛出验证错误,因为用户已经是该电子邮件地址的所有者。

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

1use Illuminate\Support\Facades\Validator;
2use Illuminate\Validation\Rule;
3 
4Validator::make($data, [
5 'email' => [
6 'required',
7 Rule::unique('users')->ignore($user->id),
8 ],
9]);

您绝对不应该将任何用户控制的请求输入传递​​到该ignore方法中。相反,您应该只传递系统生成的唯一 ID,例如来自 Eloquent 模型实例的自增 ID 或 UUID。否则,您的应用程序将容易受到 SQL 注入攻击。

除了将模型键的值传递给该ignore方法之外,您还可以传递整个模型实例。Laravel 会自动从模型中提取键:

1Rule::unique('users')->ignore($user)

如果您的表使用除 之外的主键列名id,则可以在调用该方法时指定列的名称ignore

1Rule::unique('users')->ignore($user->id, 'user_id')

默认情况下,unique规则将检查与被验证属性名称匹配的列的唯一性。但是,你可以将其他列名作为第二个参数传递给该unique方法:

1Rule::unique('users', 'email_address')->ignore($user->id)

添加额外的 Where 子句:

您可以使用 方法来自定义查询,从而指定其他查询条件where。例如,让我们添加一个查询条件,将查询范围限定为仅搜索具有account_id列值为 的记录1

1'email' => Rule::unique('users')->where(fn (Builder $query) => $query->where('account_id', 1))

在唯一性检查中忽略软删除记录:

默认情况下,唯一性规则在确定唯一性时会包含软删除记录。要从唯一性检查中排除软删除记录,可以调用该withoutTrashed方法:

1Rule::unique('users')->withoutTrashed();

如果您的模型使用除软删除记录以外的列名deleted_at,则可以在调用该方法时提供列名withoutTrashed

1Rule::unique('users')->withoutTrashed('was_deleted_at');

大写

验证的字段必须是大写。

网址

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

如果您想指定应被视为有效的 URL 协议,您可以将协议作为验证规则参数传递:

1'url' => 'url:http,https',
2 
3'game' => 'url:minecraft,steam',

乌利德

验证下的字段必须是有效的通用唯一词典排序标识符(ULID)。

唯一标识符

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

您还可以验证给定的 UUID 是否按版本匹配 UUID 规范:

1'uuid' => 'uuid:4'

有条件地添加规则

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

您可能偶尔希望,如果某个字段具有给定值,则不验证该字段。您可以使用exclude_if验证规则来实现这一点。在此示例中,如果字段的值为 ,则appointment_datedoctor_name字段将不进行验证has_appointmentfalse

1use Illuminate\Support\Facades\Validator;
2 
3$validator = Validator::make($data, [
4 'has_appointment' => 'required|boolean',
5 'appointment_date' => 'exclude_if:has_appointment,false|required|date',
6 'doctor_name' => 'exclude_if:has_appointment,false|required|string',
7]);

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

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

存在时验证

在某些情况下,您可能希望当某个字段存在于被验证的数据中时才对该字段运行验证检查。要快速实现此目的,请将以下sometimes规则添加到您的规则列表中:

1$validator = Validator::make($data, [
2 'email' => 'sometimes|required|email',
3]);

在上面的例子中,email只有当字段存在于$data数组中时才会进行验证。

如果您尝试验证一个应该始终存在但可能为空的字段,请查看有关可选字段的说明

复杂条件验证

有时您可能希望添加基于更复杂条件逻辑的验证规则。例如,您可能希望仅当另一个字段的值大于 100 时才要求某个字段生效。或者,您可能希望仅当另一个字段存在时,两个字段才具有给定值。添加这些验证规则并不麻烦。首先,创建一个包含永不更改的静态规则Validator的实例:

1use Illuminate\Support\Facades\Validator;
2 
3$validator = Validator::make($request->all(), [
4 'email' => 'required|email',
5 'games' => 'required|integer|min:0',
6]);

假设我们的 Web 应用面向游戏Collections者。如果一位游戏Collections者在我们的应用中注册,并且拥有超过 100 款游戏,我们希望他们解释一下为什么拥有这么多游戏。例如,他们可能经营一家游戏转售商店,或者只是喜欢Collections游戏。为了有条件地添加此要求,我们可以sometimesValidator实例上使用该方法。

1use Illuminate\Support\Fluent;
2 
3$validator->sometimes('reason', 'required|max:500', function (Fluent $input) {
4 return $input->games >= 100;
5});

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

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

传递给闭包的参数$input将是一个实例Illuminate\Support\Fluent,可用于访问您的输入和验证下的文件。

复杂条件数组验证

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

1$input = [
2 'channels' => [
3 [
4 'type' => 'email',
5 'address' => 'abigail@example.com',
6 ],
7 [
8 'type' => 'url',
9 'address' => 'https://example.com',
10 ],
11 ],
12];
13 
14$validator->sometimes('channels.*.address', 'email', function (Fluent $input, Fluent $item) {
15 return $item->type === 'email';
16});
17 
18$validator->sometimes('channels.*.address', 'url', function (Fluent $input, Fluent $item) {
19 return $item->type !== 'email';
20});

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

验证数组

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

1use Illuminate\Support\Facades\Validator;
2 
3$input = [
4 'user' => [
5 'name' => 'Taylor Otwell',
6 'username' => 'taylorotwell',
7 'admin' => true,
8 ],
9];
10 
11Validator::make($input, [
12 'user' => 'array:name,username',
13]);

一般来说,你应该始终指定允许在数组中出现的数组键。否则,验证器的validatevalidated方法将返回所有已验证的数据,包括数组及其所有键,即使这些键未被其他嵌套数组验证规则验证。

验证嵌套数组输入

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

1use Illuminate\Support\Facades\Validator;
2 
3$validator = Validator::make($request->all(), [
4 'photos.profile' => 'required|image',
5]);

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

1$validator = Validator::make($request->all(), [
2 'person.*.email' => 'email|unique:users',
3 'person.*.first_name' => 'required_with:person.*.last_name',
4]);

同样,您可以在语言文件中*指定自定义验证消息时使用字符,从而可以轻松地对基于数组的字段使用单个验证消息:

1'custom' => [
2 'person.*.email' => [
3 'unique' => 'Each person must have a unique email address',
4 ]
5],

访问嵌套数组数据

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

1use App\Rules\HasPermission;
2use Illuminate\Support\Facades\Validator;
3use Illuminate\Validation\Rule;
4 
5$validator = Validator::make($request->all(), [
6 'companies.*.id' => Rule::forEach(function (string|null $value, string $attribute) {
7 return [
8 Rule::exists(Company::class, 'id'),
9 new HasPermission('manage-company', $value),
10 ];
11 }),
12]);

错误消息索引和位置

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

1use Illuminate\Support\Facades\Validator;
2 
3$input = [
4 'photos' => [
5 [
6 'name' => 'BeachVacation.jpg',
7 'description' => 'A photo of my beach vacation!',
8 ],
9 [
10 'name' => 'GrandCanyon.jpg',
11 'description' => '',
12 ],
13 ],
14];
15 
16Validator::validate($input, [
17 'photos.*.description' => 'required',
18], [
19 'photos.*.description.required' => 'Please describe photo #:position.',
20]);

鉴于上述示例,验证将失败,并且用户将看到以下错误“请描述照片#2”。

如果需要,您可以通过second-index、、、等引用更深层嵌套的索引和位置second-positionthird-indexthird-position

1'photos.*.attributes.*.string' => 'Invalid attribute for photo #:second-position.',

验证文件

Laravel 提供了多种可用于验证上传文件的验证规则,例如mimesimageminmax。虽然你可以在验证文件时单独指定这些规则,但 Laravel 还提供了一个流畅的文件验证规则生成器,你可能会觉得它很方便:

1use Illuminate\Support\Facades\Validator;
2use Illuminate\Validation\Rules\File;
3 
4Validator::validate($input, [
5 'attachment' => [
6 'required',
7 File::types(['mp3', 'wav'])
8 ->min(1024)
9 ->max(12 * 1024),
10 ],
11]);

验证文件类型

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

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

验证文件大小

为方便起见,可以将最小和最大文件大小指定为字符串,并添加表示文件大小单位的后缀。支持kbmbgbtb后缀:

1File::types(['mp3', 'wav'])
2 ->min('1kb')
3 ->max('10mb');

验证图像文件

如果您的应用程序接受用户上传的图像,您可以使用File规则的image构造函数方法来确保验证的文件是图像(jpg,jpeg,png,bmp,gif或webp)。

此外,该dimensions规则可用于限制图像的尺寸:

1use Illuminate\Support\Facades\Validator;
2use Illuminate\Validation\Rule;
3use Illuminate\Validation\Rules\File;
4 
5Validator::validate($input, [
6 'photo' => [
7 'required',
8 File::image()
9 ->min(1024)
10 ->max(12 * 1024)
11 ->dimensions(Rule::dimensions()->maxWidth(1000)->maxHeight(500)),
12 ],
13]);

有关验证图像尺寸的更多信息,请参阅尺寸规则文档

默认情况下,image由于可能存在 XSS 漏洞,该规则不允许 SVG 文件。如果您需要允许 SVG 文件,可以allowSvg: trueimage规则传递:File::image(allowSvg: true)

验证图像尺寸

您还可以验证图片的尺寸。例如,要验证上传的图片宽度至少为 1000 像素,高度至少为 500 像素,您可以使用以下dimensions规则:

1use Illuminate\Validation\Rule;
2use Illuminate\Validation\Rules\File;
3 
4File::image()->dimensions(
5 Rule::dimensions()
6 ->maxWidth(1000)
7 ->maxHeight(500)
8)

有关验证图像尺寸的更多信息,请参阅尺寸规则文档

验证密码

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

1use Illuminate\Support\Facades\Validator;
2use Illuminate\Validation\Rules\Password;
3 
4$validator = Validator::make($request->all(), [
5 'password' => ['required', 'confirmed', Password::min(8)],
6]);

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

1// Require at least 8 characters...
2Password::min(8)
3 
4// Require at least one letter...
5Password::min(8)->letters()
6 
7// Require at least one uppercase and one lowercase letter...
8Password::min(8)->mixedCase()
9 
10// Require at least one number...
11Password::min(8)->numbers()
12 
13// Require at least one symbol...
14Password::min(8)->symbols()

此外,您可以使用以下方法确保密码在公共密码数据泄露中没有被泄露uncompromised

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

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

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

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

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

1Password::min(8)
2 ->letters()
3 ->mixedCase()
4 ->numbers()
5 ->symbols()
6 ->uncompromised()

定义默认密码规则

您可能会发现,在应用程序的单个位置指定密码的默认验证规则非常方便。您可以使用Password::defaults接受闭包的方法轻松实现这一点。传递给该方法的闭包defaults应该返回密码规则的默认配置。通常,defaults应该在boot应用程序的某个服务提供商的方法中调用该规则:

1use Illuminate\Validation\Rules\Password;
2 
3/**
4 * Bootstrap any application services.
5 */
6public function boot(): void
7{
8 Password::defaults(function () {
9 $rule = Password::min(8);
10 
11 return $this->app->isProduction()
12 ? $rule->mixedCase()->uncompromised()
13 : $rule;
14 });
15}

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

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

有时,您可能希望在默认密码验证规则中附加其他验证规则。您可以使用rules以下方法来实现:

1use App\Rules\ZxcvbnRule;
2 
3Password::defaults(function () {
4 $rule = Password::min(8)->rules([new ZxcvbnRule]);
5 
6 // ...
7});

自定义验证规则

使用规则对象

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

1php artisan make:rule Uppercase

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

1<?php
2 
3namespace App\Rules;
4 
5use Closure;
6use Illuminate\Contracts\Validation\ValidationRule;
7 
8class Uppercase implements ValidationRule
9{
10 /**
11 * Run the validation rule.
12 */
13 public function validate(string $attribute, mixed $value, Closure $fail): void
14 {
15 if (strtoupper($value) !== $value) {
16 $fail('The :attribute must be uppercase.');
17 }
18 }
19}

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

1use App\Rules\Uppercase;
2 
3$request->validate([
4 'name' => ['required', 'string', new Uppercase],
5]);

翻译验证消息

除了向闭包提供文字错误消息之外$fail,您还可以提供翻译字符串键并指示 Laravel 翻译错误消息:

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

如果需要,您可以提供占位符替换和首选语言作为该translate方法的第一个和第二个参数:

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

访问其他数据

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

1<?php
2 
3namespace App\Rules;
4 
5use Illuminate\Contracts\Validation\DataAwareRule;
6use Illuminate\Contracts\Validation\ValidationRule;
7 
8class Uppercase implements DataAwareRule, ValidationRule
9{
10 /**
11 * All of the data under validation.
12 *
13 * @var array<string, mixed>
14 */
15 protected $data = [];
16 
17 // ...
18 
19 /**
20 * Set the data under validation.
21 *
22 * @param array<string, mixed> $data
23 */
24 public function setData(array $data): static
25 {
26 $this->data = $data;
27 
28 return $this;
29 }
30}

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

1<?php
2 
3namespace App\Rules;
4 
5use Illuminate\Contracts\Validation\ValidationRule;
6use Illuminate\Contracts\Validation\ValidatorAwareRule;
7use Illuminate\Validation\Validator;
8 
9class Uppercase implements ValidationRule, ValidatorAwareRule
10{
11 /**
12 * The validator instance.
13 *
14 * @var \Illuminate\Validation\Validator
15 */
16 protected $validator;
17 
18 // ...
19 
20 /**
21 * Set the current validator.
22 */
23 public function setValidator(Validator $validator): static
24 {
25 $this->validator = $validator;
26 
27 return $this;
28 }
29}

使用闭包

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

1use Illuminate\Support\Facades\Validator;
2use Closure;
3 
4$validator = Validator::make($request->all(), [
5 'title' => [
6 'required',
7 'max:255',
8 function (string $attribute, mixed $value, Closure $fail) {
9 if ($value === 'foo') {
10 $fail("The {$attribute} is invalid.");
11 }
12 },
13 ],
14]);

隐含规则

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

1use Illuminate\Support\Facades\Validator;
2 
3$rules = ['name' => 'unique:users,name'];
4 
5$input = ['name' => ''];
6 
7Validator::make($input, $rules)->passes(); // true

即使属性为空,自定义规则仍会运行,但规则必须暗示该属性是必需的。要快速生成新的隐式规则对象,可以使用make:ruleArtisan 命令并附带以下--implicit选项:

1php artisan make:rule Uppercase --implicit

“隐式”规则仅暗示该属性是必需的。至于是否真正使缺失或为空的属性无效,则由您自行决定。