跳到內容

驗證

簡介

Laravel 提供了幾種不同的方法來驗證應用程式的傳入資料。最常見的是使用所有傳入的 HTTP 請求上可用的 validate 方法。但是,我們也將討論其他驗證方法。

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 方法中填寫邏輯以驗證新的部落格文章。為此,我們將使用 Illuminate\Http\Request 物件提供的 validate 方法。如果驗證規則通過,您的程式碼將繼續正常執行;但是,如果驗證失敗,將拋出 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]);

在此範例中,如果 title 屬性上的 unique 規則失敗,則不會檢查 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\ShareErrorsFromSession 中介層與您應用程式的所有視圖共用,該中介層由 web 中介層群組提供。當應用此中介層時,$errors 變數將始終在您的視圖中可用,讓您可以方便地假設 $errors 變數始終已定義且可以安全地使用。$errors 變數將是 Illuminate\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 目錄,您可以指示 Laravel 使用 lang:publish Artisan 命令建立它。

lang/en/validation.php 檔案中,您將找到每個驗證規則的翻譯條目。您可以根據應用程式的需求自由變更或修改這些訊息。

此外,您可以將此檔案複製到另一個語言目錄,以翻譯應用程式語言的訊息。若要了解有關 Laravel 本地化的更多資訊,請查看完整的本地化文件

預設情況下,Laravel 應用程式骨架不包含 lang 目錄。如果您想要自訂 Laravel 的語言檔案,您可以透過 lang:publish Artisan 命令發佈它們。

XHR 請求和驗證

在此範例中,我們使用傳統表單將資料傳送到應用程式。但是,許多應用程式從 JavaScript 驅動的前端接收 XHR 請求。在 XHR 請求期間使用 validate 方法時,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。這樣做是為了讓您可以方便地在下一個請求期間存取輸入並重新填充使用者嘗試提交的表單。

若要從先前的請求中檢索快閃輸入,請在 Illuminate\Http\Request 的實例上調用 old 方法。old 方法將從session中提取先前快閃的輸入資料

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

Laravel 還提供了一個全域 old 輔助函數。如果您在 Blade 模板中顯示舊輸入,則使用 old 輔助函數重新填充表單會更方便。如果給定欄位不存在舊輸入,則會傳回 null

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

關於可選欄位的注意事項

預設情況下,Laravel 在應用程式的全域中介層堆疊中包含 TrimStringsConvertEmptyStringsToNull 中介層。因此,如果您不希望驗證器將 null 值視為無效,您通常需要將「可選」請求欄位標記為 nullable。例如

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 Entity HTTP 回應。

在下方,您可以查看驗證錯誤的 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:request Artisan 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}

您可以在 rules 方法的簽名中類型提示您需要的任何依賴項。它們將透過 Laravel 服務容器自動解析。

那麼,如何評估驗證規則?您需要做的就是在控制器方法上類型提示請求。傳入的表單請求會在呼叫控制器方法之前進行驗證,這表示您不需要使用任何驗證邏輯來混亂您的控制器

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}

如果驗證失敗,則會產生重新導向回應,將使用者傳送回他們先前的位置。錯誤也會快閃到 session,以便它們可用於顯示。如果請求是 XHR 請求,則會傳回 HTTP 回應,其中包含 422 狀態碼,其中包括驗證錯誤的 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}

您可以在 authorize 方法的簽名中類型提示您需要的任何依賴項。它們將透過 Laravel 服務容器自動解析。

自訂錯誤訊息

您可以透過覆寫 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 建立驗證器實例。facade 上的 make 方法會產生新的驗證器實例

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 方法將錯誤訊息快閃到 session。使用此方法時,$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');

然後,您可以從 $errors 變數存取具名 MessageBag 實例

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 方法也接受可調用陣列,如果您的「驗證後」邏輯封裝在可調用類別中,這尤其方便,這些類別將透過其 __invoke 方法接收 Illuminate\Validation\Validator 實例

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();

使用錯誤訊息

Validator 實例上呼叫 errors 方法後,您將收到 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 目錄,您可以指示 Laravel 使用 lang:publish Artisan 命令建立它。

lang/en/validation.php 檔案中,您將找到每個驗證規則的翻譯條目。您可以根據應用程式的需求自由變更或修改這些訊息。

此外,您可以將此檔案複製到另一個語言目錄,以翻譯應用程式語言的訊息。若要了解有關 Laravel 本地化的更多資訊,請查看完整的本地化文件

預設情況下,Laravel 應用程式骨架不包含 lang 目錄。如果您想要自訂 Laravel 的語言檔案,您可以透過 lang:publish Artisan 命令發佈它們。

特定屬性的自訂訊息

您可以在應用程式的驗證語言檔案中自訂用於指定屬性和規則組合的錯誤訊息。為此,請將您的訊息自訂新增至應用程式 lang/xx/validation.php 語言檔案的 custom 陣列

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 部分替換為自訂值,您可以在 lang/xx/validation.php 語言檔案的 attributes 陣列中指定自訂屬性名稱

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

預設情況下,Laravel 應用程式骨架不包含 lang 目錄。如果您想要自訂 Laravel 的語言檔案,您可以透過 lang:publish Artisan 命令發佈它們。

在語言檔案中指定值

Laravel 的某些內建驗證規則錯誤訊息包含 :value 佔位符,該佔位符會替換為請求屬性的目前值。但是,您有時可能需要將驗證訊息的 :value 部分替換為值的自訂表示形式。例如,考慮以下規則,該規則指定如果 payment_type 的值為 cc,則需要信用卡號碼

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.

您可以透過在 lang/xx/validation.php 語言檔案中定義 values 陣列,來指定更使用者友善的值表示形式,而不是顯示 cc 作為付款類型值

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

預設情況下,Laravel 應用程式骨架不包含 lang 目錄。如果您想要自訂 Laravel 的語言檔案,您可以透過 lang:publish Artisan 命令發佈它們。

在定義此值後,驗證規則將產生以下錯誤訊息

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

可用的驗證規則

以下是所有可用的驗證規則及其功能的清單

布林值

字串

數字

陣列

日期 (Dates)

檔案 (Files)

資料庫

工具 (Utilities)

accepted

驗證欄位的值必須為 "yes""on"1"1"true"true"。這對於驗證「服務條款」接受條款或類似欄位非常有用。

accepted_if:anotherfield,value,...

若另一個驗證欄位等於指定的值,則驗證欄位的值必須為 "yes""on"1"1"true"true"。這對於驗證「服務條款」接受條款或類似欄位非常有用。

active_url

驗證欄位必須根據 PHP 的 dns_get_record 函數具有有效的 A 或 AAAA 記錄。提供的 URL 主機名稱會先使用 PHP 的 parse_url 函數提取,然後再傳遞給 dns_get_record

after:date

驗證欄位的值必須是給定日期之後的日期。日期將傳遞到 PHP 的 strtotime 函數中,以便轉換為有效的 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],

afterTodaytodayOrAfter 方法可以用於流暢地表達日期必須在今天之後,或今天或今天之後。

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

after_or_equal:date

驗證欄位的值必須是給定日期之後或相等的日期。有關更多資訊,請參閱 after 規則。

為了方便起見,日期相關的規則可以使用流暢的 date 規則建立器來建構。

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

alpha

驗證欄位必須完全由 Unicode 字母字元組成,包含在 \p{L}\p{M} 中。

若要將此驗證規則限制為 ASCII 範圍 (a-zA-Z) 中的字元,您可以為驗證規則提供 ascii 選項。

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

alpha_dash

驗證欄位必須完全由 Unicode 字母數字字元組成,包含在 \p{L}\p{M}\p{N},以及 ASCII 破折號 (-) 和 ASCII 底線 (_)。

若要將此驗證規則限制為 ASCII 範圍 (a-zA-Z) 中的字元,您可以為驗證規則提供 ascii 選項。

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

alpha_num

驗證欄位必須完全由 Unicode 字母數字字元組成,包含在 \p{L}\p{M}\p{N} 中。

若要將此驗證規則限制為 ASCII 範圍 (a-zA-Z) 中的字元,您可以為驗證規則提供 ascii 選項。

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

array

驗證欄位必須是 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

在第一次驗證失敗後,停止執行欄位的驗證規則。

雖然 bail 規則只會在遇到驗證失敗時停止驗證特定欄位,但 stopOnFirstFailure 方法會通知驗證器,一旦發生單次驗證失敗,就應該停止驗證所有屬性。

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

before:date

驗證欄位的值必須是給定日期之前的日期。日期將傳遞到 PHP 的 strtotime 函數中,以便轉換為有效的 DateTime 實例。此外,與 after 規則一樣,另一個驗證欄位的名稱可以作為 date 的值提供。

為了方便起見,日期相關的規則也可以使用流暢的 date 規則建立器來建構。

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

beforeTodaytodayOrBefore 方法可以用於流暢地表達日期必須在今天之前,或今天或今天之前。

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

before_or_equal:date

驗證欄位的值必須是給定日期之前或相等的日期。日期將傳遞到 PHP 的 strtotime 函數中,以便轉換為有效的 DateTime 實例。此外,與 after 規則一樣,另一個驗證欄位的名稱可以作為 date 的值提供。

為了方便起見,日期相關的規則也可以使用流暢的 date 規則建立器來建構。

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

between:min,max

驗證欄位的大小必須介於給定的 minmax 之間(包含)。字串、數值、陣列和檔案的評估方式與 size 規則相同。

boolean

驗證欄位必須能夠轉換為布林值。接受的輸入為 truefalse10"1""0"

confirmed

驗證欄位必須具有相符的 {field}_confirmation 欄位。例如,如果驗證欄位是 password,則輸入中必須存在相符的 password_confirmation 欄位。

您也可以傳遞自訂確認欄位名稱。例如,confirmed:repeat_username 將預期 repeat_username 欄位與驗證欄位相符。

contains:foo,bar,...

驗證欄位必須是一個包含所有給定參數值的陣列。

current_password

驗證欄位必須與已驗證使用者的密碼相符。您可以使用規則的第一個參數指定驗證守衛

1'password' => 'current_password:api'

date

根據 PHP 的 strtotime 函數,驗證欄位必須是有效的非相對日期。

date_equals:date

驗證欄位必須等於給定的日期。日期將傳遞到 PHP 的 strtotime 函數中,以便轉換為有效的 DateTime 實例。

date_format:format,...

驗證欄位必須與給定的其中一種 format 相符。驗證欄位時,您應該使用 datedate_format 其中之一,而不是兩者都使用。此驗證規則支援 PHP DateTime 類別支援的所有格式。

為了方便起見,日期相關的規則可以使用流暢的 date 規則建立器來建構。

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

decimal:min,max

驗證欄位必須是數值,並且必須包含指定的小數位數。

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'

declined

驗證欄位必須為 "no""off"0"0"false"false"

declined_if:anotherfield,value,...

若另一個驗證欄位等於指定的值,則驗證欄位必須為 "no""off"0"0"false"false"

different:field

驗證欄位的值必須與 field 不同。

digits:value

驗證欄位的整數必須具有 value 的確切長度。

digits_between:min,max

整數驗證的長度必須介於給定的 minmax 之間。

dimensions

驗證欄位的檔案必須是符合規則參數指定尺寸約束的圖片。

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

可用的約束條件為:min_widthmax_widthmin_heightmax_heightwidthheightratio

ratio 約束條件應表示為寬度除以高度。這可以使用分數(如 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]);

distinct

驗證陣列時,驗證欄位不得有任何重複值。

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

Distinct 預設使用寬鬆的變數比較。若要使用嚴格比較,您可以將 strict 參數新增到您的驗證規則定義中。

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

您可以將 ignore_case 新增到驗證規則的引數中,使規則忽略大小寫差異。

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

doesnt_start_with:foo,bar,...

驗證欄位不得以給定的其中一個值開頭。

doesnt_end_with:foo,bar,...

驗證欄位不得以給定的其中一個值結尾。

email

驗證欄位的格式必須為電子郵件地址。此驗證規則使用 egulias/email-validator 套件來驗證電子郵件地址。預設情況下,會套用 RFCValidation 驗證器,但您也可以套用其他驗證樣式。

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

上面的範例將套用 RFCValidationDNSCheckValidation 驗證。以下是您可以套用的驗證樣式完整列表:

  • rfc: RFCValidation - 根據 RFC 5322 驗證電子郵件地址。
  • strict: NoRFCWarningsValidation - 根據 RFC 5322 驗證電子郵件,拒絕尾隨句點或多個連續句點。
  • dns: DNSCheckValidation - 確保電子郵件地址的網域具有有效的 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]);

dnsspoof 驗證器需要 PHP intl 擴充功能。

ends_with:foo,bar,...

驗證欄位必須以給定的其中一個值結尾。

enum

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 );

exclude

驗證欄位將從 validatevalidated 方法傳回的請求資料中排除。

exclude_if:anotherfield,value

如果 anotherfield 欄位等於 value,則驗證欄位將從 validatevalidated 方法傳回的請求資料中排除。

如果需要複雜的條件排除邏輯,您可以利用 Rule::excludeIf 方法。此方法接受布林值或閉包。當給定閉包時,閉包應傳回 truefalse 以指示是否應排除驗證欄位。

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

除非 anotherfield 欄位等於 value,否則驗證欄位將從 validatevalidated 方法傳回的請求資料中排除。如果 valuenull (exclude_unless:name,null),則除非比較欄位為 null 或比較欄位在請求資料中遺失,否則驗證欄位將被排除。

exclude_with:anotherfield

如果 anotherfield 欄位存在,則驗證欄位將從 validatevalidated 方法傳回的請求資料中排除。

exclude_without:anotherfield

如果 anotherfield 欄位不存在,則驗證欄位將從 validatevalidated 方法傳回的請求資料中排除。

exists:table,column

驗證欄位必須存在於給定的資料庫表格中。

Exists 規則的基本用法

1'state' => 'exists:states'

如果未指定 column 選項,則將使用欄位名稱。因此,在這種情況下,規則將驗證 states 資料庫表格是否包含一筆記錄,其 state 欄位值與請求的 state 屬性值相符。

指定自訂欄位名稱

您可以透過將資料庫欄位名稱放在資料庫表格名稱之後,明確指定驗證規則應使用的資料庫欄位名稱。

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::exists 方法產生的 exists 規則應使用的資料庫欄位名稱。

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

extensions:foo,bar,...

驗證欄位的檔案必須具有與列出的其中一個副檔名相對應的使用者指定副檔名。

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

您永遠不應僅依靠驗證檔案的使用者指定副檔名。此規則通常應始終與 mimesmimetypes 規則結合使用。

file

驗證欄位必須是成功上傳的檔案。

filled

驗證欄位存在時不得為空。

gt:field

驗證欄位的值必須大於給定的 fieldvalue。這兩個欄位必須屬於同一類型。字串、數值、陣列和檔案的評估方式與 size 規則使用相同的慣例。

gte:field

驗證欄位的值必須大於或等於給定的 fieldvalue。這兩個欄位必須屬於同一類型。字串、數值、陣列和檔案的評估方式與 size 規則使用相同的慣例。

hex_color

驗證欄位必須包含 十六進位 格式的有效顏色值。

image

驗證欄位的檔案必須是圖片 (jpg、jpeg、png、bmp、gif 或 webp)。

預設情況下,由於可能存在 XSS 漏洞,因此圖片規則不允許 SVG 檔案。如果您需要允許 SVG 檔案,可以為 image 規則提供 allow_svg 指令 (image:allow_svg)。

in:foo,bar,...

驗證欄位必須包含在給定的值列表中。由於此規則通常需要您 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.*

驗證欄位必須存在於 anotherfield 的值中。

integer

驗證欄位必須是整數。

此驗證規則不驗證輸入是否為「整數」變數類型,僅驗證輸入是否為 PHP 的 FILTER_VALIDATE_INT 規則接受的類型。如果您需要驗證輸入是否為數字,請將此規則與 numeric 驗證規則結合使用。

ip

驗證欄位必須是 IP 地址。

ipv4

驗證欄位必須是 IPv4 地址。

ipv6

驗證欄位必須是 IPv6 地址。

json

驗證欄位必須是有效的 JSON 字串。

lt:field

驗證欄位的值必須小於給定的 field。這兩個欄位必須屬於同一類型。字串、數值、陣列和檔案的評估方式與 size 規則使用相同的慣例。

lte:field

驗證欄位的值必須小於或等於給定的 field。這兩個欄位必須屬於同一類型。字串、數值、陣列和檔案的評估方式與 size 規則使用相同的慣例。

lowercase

驗證欄位必須是小寫。

list

驗證欄位必須是一個列表陣列。如果陣列的鍵由從 0 到 count($array) - 1 的連續數字組成,則該陣列被視為列表。

mac_address

驗證欄位必須是 MAC 地址。

max:value

驗證欄位的值必須小於或等於最大 value。字串、數值、陣列和檔案的評估方式與 size 規則相同。

max_digits:value

驗證欄位的整數長度不得超過 value

mimetypes:text/plain,...

驗證欄位的檔案必須與給定的其中一種 MIME 類型相符。

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

為了確定上傳檔案的 MIME 類型,將會讀取檔案的內容,並且框架將嘗試猜測 MIME 類型,這可能與用戶端提供的 MIME 類型不同。

mimes:foo,bar,...

驗證欄位的檔案必須具有與列出的其中一個副檔名相對應的 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。如果您想驗證檔案的使用者指派副檔名,可以使用 extensions 規則。

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 方法來流暢地建構規則。

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

not_regex:pattern

驗證欄位不得與給定的正規表示式相符。

在內部,此規則使用 PHP 的 preg_match 函數。指定的模式應遵守 preg_match 所需的相同格式,因此也應包含有效的定界符。例如:'email' => 'not_regex:/^.+$/i'

使用 regex / not_regex 模式時,可能需要使用陣列而不是使用 | 分隔符號來指定驗證規則,尤其是在正規表示式包含 | 字元的情況下。

nullable

驗證欄位可以為 null

numeric

驗證欄位必須是數值

present

驗證欄位必須存在於輸入資料中。

present_if:anotherfield,value,...

如果 anotherfield 欄位等於任何 value,則驗證欄位必須存在。

present_unless:anotherfield,value

除非 anotherfield 欄位等於任何 value,否則驗證欄位必須存在。

present_with:foo,bar,...

僅當 任何其他指定欄位存在時,驗證欄位才必須存在。

present_with_all:foo,bar,...

僅當 所有其他指定欄位都存在時,驗證欄位才必須存在。

prohibited

驗證欄位必須遺失或為空。如果欄位符合以下其中一個條件,則為「空」。

  • 值為 null
  • 值為空字串。
  • 值為空陣列或空 Countable 物件。
  • 值為路徑為空的已上傳檔案。

prohibited_if:anotherfield,value,...

如果 anotherfield 欄位等於任何 value,則驗證欄位必須遺失或為空。如果欄位符合以下其中一個條件,則為「空」。

  • 值為 null
  • 值為空字串。
  • 值為空陣列或空 Countable 物件。
  • 值為路徑為空的已上傳檔案。

如果需要複雜的條件禁止邏輯,您可以利用 Rule::prohibitedIf 方法。此方法接受布林值或閉包。當給定閉包時,閉包應傳回 truefalse 以指示是否應禁止驗證欄位。

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]);

prohibited_unless:anotherfield,value,...

除非 anotherfield 欄位等於任何 value,否則驗證欄位必須遺失或為空。如果欄位符合以下其中一個條件,則為「空」。

  • 值為 null
  • 值為空字串。
  • 值為空陣列或空 Countable 物件。
  • 值為路徑為空的已上傳檔案。

prohibits:anotherfield,...

如果驗證欄位不遺失或為空,則 anotherfield 中的所有欄位都必須遺失或為空。如果欄位符合以下其中一個條件,則為「空」。

  • 值為 null
  • 值為空字串。
  • 值為空陣列或空 Countable 物件。
  • 值為路徑為空的已上傳檔案。

regex:pattern

驗證欄位必須與給定的正規表示式相符。

在內部,此規則使用 PHP 的 preg_match 函數。指定的模式應遵守 preg_match 所需的相同格式,因此也應包含有效的定界符。例如:'email' => 'regex:/^.+@.+$/i'

使用 regex / not_regex 模式時,可能需要使用陣列而不是使用 | 分隔符號來指定規則,尤其是在正規表示式包含 | 字元的情況下。

required

驗證欄位必須存在於輸入資料中且不得為空。如果欄位符合以下其中一個條件,則為「空」。

  • 值為 null
  • 值為空字串。
  • 值為空陣列或空 Countable 物件。
  • 值為沒有路徑的已上傳檔案。

required_if:anotherfield,value,...

如果 anotherfield 欄位等於任何 value,則驗證欄位必須存在且不得為空。

如果您想為 required_if 規則建構更複雜的條件,可以使用 Rule::requiredIf 方法。此方法接受布林值或閉包。當傳遞閉包時,閉包應傳回 truefalse 以指示驗證欄位是否為必填。

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]);

required_if_accepted:anotherfield,...

如果 anotherfield 欄位等於 "yes""on"1"1"true"true",則驗證欄位必須存在且不得為空。

required_if_declined:anotherfield,...

如果 anotherfield 欄位等於 "no""off"0"0"false"false",則驗證欄位必須存在且不得為空。

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 對應於給定的整數值(屬性也必須具有 numericinteger 規則)。對於陣列,size 對應於陣列的 count。對於檔案,size 對應於檔案大小(以 KB 為單位)。讓我們看一些範例:

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';

starts_with:foo,bar,...

驗證欄位必須以給定的其中一個值開頭。

string

驗證欄位必須是字串。如果您想允許欄位也可以為 null,則應將 nullable 規則指派給該欄位。

timezone

驗證欄位必須是根據 DateTimeZone::listIdentifiers 方法的有效時區識別碼。

DateTimeZone::listIdentifiers 方法接受的引數也可以提供給此驗證規則。

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

unique:table,column

驗證欄位不得存在於給定的資料庫表格中。

指定自訂表格/欄位名稱

您可以指定應使用的 Eloquent 模型來確定表格名稱,而不是直接指定表格名稱。

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

column 選項可用於指定欄位對應的資料庫欄位。如果未指定 column 選項,則將使用驗證欄位的名稱。

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

指定自訂資料庫連線

有時,您可能需要為驗證器執行的資料庫查詢設定自訂連線。若要完成此操作,您可以在表格名稱前面加上連線名稱。

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

強制 Unique 規則忽略給定的 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))

在唯一性檢查中忽略軟刪除的記錄

預設情況下,unique 規則在判斷唯一性時會包含軟刪除的記錄。若要從唯一性檢查中排除軟刪除的記錄,您可以調用 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

驗證欄位的值必須為有效的 通用唯一詞彙可排序識別碼 (ULID)。

UUID

驗證欄位的值必須為有效的 RFC 9562(版本 1、3、4、5、6、7 或 8)通用唯一識別碼 (UUID)。

您也可以驗證給定的 UUID 是否符合特定版本的 UUID 規範

1'uuid' => 'uuid:4'

有條件地新增規則

當欄位具有特定值時跳過驗證

您有時可能希望在另一個欄位具有給定值時,不驗證給定的欄位。您可以使用 exclude_if 驗證規則來完成此操作。在此範例中,如果 has_appointment 欄位的值為 false,則不會驗證 appointment_datedoctor_name 欄位

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|numeric',
6]);

假設我們的 Web 應用程式適用於遊戲收藏家。如果遊戲收藏家在我們的應用程式中註冊,並且他們擁有超過 100 款遊戲,我們希望他們解釋為什麼他們擁有這麼多遊戲。例如,也許他們經營一家遊戲轉售商店,或者也許他們只是喜歡收藏遊戲。為了有條件地新增此要求,我們可以在 Validator 實例上使用 sometimes 方法。

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' => '[email protected]',
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 驗證規則文件中所述,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(從 0 開始)和 :position(從 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-indexsecond-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]);

有關驗證圖片尺寸的更多資訊,請參閱尺寸規則文件

預設情況下,由於可能存在 XSS 漏洞,image 規則不允許 SVG 檔案。如果您需要允許 SVG 檔案,您可以將 allowSvg: true 傳遞給 image 規則: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 規則物件可讓您輕鬆自訂應用程式的密碼複雜度要求,例如指定密碼至少需要一個字母、數字、符號或混合大小寫字元

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-匿名性 模型,透過 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 方法的閉包應傳回 Password 規則的預設配置。通常,應在應用程式的其中一個服務提供者的 boot 方法中調用 defaults 規則

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});

自訂驗證規則

使用 Rule 物件

Laravel 提供了各種有用的驗證規則;但是,您可能希望指定一些您自己的規則。註冊自訂驗證規則的一種方法是使用規則物件。若要產生新的規則物件,您可以使用 make:rule Artisan 命令。讓我們使用此命令來產生一個驗證字串是否為大寫的規則。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

為了使自訂規則即使在屬性為空時也能執行,規則必須暗示該屬性是必需的。若要快速產生新的隱含規則物件,您可以使用帶有 --implicit 選項的 make:rule Artisan 命令

1php artisan make:rule Uppercase --implicit

「隱含」規則僅暗示該屬性是必需的。它是否真的會使遺失或空屬性失效取決於您。