跳到內容

驗證

簡介

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

Laravel 包含各種方便的驗證規則,您可以將這些規則應用於資料,甚至提供驗證值在給定資料庫表格中是否唯一的能耐。我們將詳細介紹每個驗證規則,以便您熟悉 Laravel 的所有驗證功能。

驗證快速入門

為了瞭解 Laravel 強大的驗證功能,讓我們看看驗證表單並將錯誤訊息顯示給使用者的完整範例。透過閱讀此高階概述,您將能夠大致瞭解如何使用 Laravel 驗證傳入的請求資料。

定義路由

首先,假設我們在 routes/web.php 檔案中定義了以下路由

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

GET 路由將顯示一個表單,供使用者建立新的部落格文章,而 POST 路由將在資料庫中儲存新的部落格文章。

建立控制器

接下來,讓我們看看一個簡單的控制器,它可以處理這些路由的傳入請求。我們先將 store 方法留空

<?php
 
namespace App\Http\Controllers;
 
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\View\View;
 
class PostController extends Controller
{
/**
* Show the form to create a new blog post.
*/
public function create(): View
{
return view('post.create');
}
 
/**
* Store a new blog post.
*/
public function store(Request $request): RedirectResponse
{
// Validate and store the blog post...
 
$post = /** ... */
 
return to_route('post.show', ['post' => $post->id]);
}
}

編寫驗證邏輯

現在我們準備好在 store 方法中填入邏輯,以驗證新的部落格文章。為此,我們將使用 Illuminate\Http\Request 物件提供的 validate 方法。如果驗證規則通過,您的程式碼將繼續正常執行;但是,如果驗證失敗,將擲回 Illuminate\Validation\ValidationException 例外狀況,並且會自動將適當的錯誤回應傳回給使用者。

如果驗證在傳統 HTTP 請求期間失敗,將會產生重新導向到先前 URL 的回應。如果傳入的請求是 XHR 請求,則會傳回包含驗證錯誤訊息的 JSON 回應

為了更好地了解 validate 方法,讓我們跳回 store 方法

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

如您所見,驗證規則會傳遞到 validate 方法中。別擔心 - 所有可用的驗證規則都已記錄。同樣地,如果驗證失敗,將會自動產生適當的回應。如果驗證通過,我們的控制器將繼續正常執行。

或者,驗證規則可以指定為規則陣列,而不是單個 | 分隔的字串

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

此外,您可以使用 validateWithBag 方法來驗證請求,並將任何錯誤訊息儲存在命名錯誤袋

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

在第一次驗證失敗時停止

有時您可能希望在第一次驗證失敗後停止在屬性上執行驗證規則。若要執行此操作,請將 bail 規則指派給屬性

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

在此範例中,如果 title 屬性的 unique 規則失敗,則不會檢查 max 規則。規則會按照指派的順序進行驗證。

關於巢狀屬性的注意事項

如果傳入的 HTTP 請求包含「巢狀」欄位資料,您可以使用「點」語法在驗證規則中指定這些欄位

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

另一方面,如果您的欄位名稱包含文字句點,您可以透過使用反斜線逸出句點來明確防止將其解譯為「點」語法

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

顯示驗證錯誤

那麼,如果傳入的請求欄位未通過指定的驗證規則,該怎麼辦?如先前所述,Laravel 會自動將使用者重新導向回他們先前的位置。此外,所有驗證錯誤和請求輸入都會自動快閃到 Session

$errors 變數由 Illuminate\View\Middleware\ShareErrorsFromSession 中介層與應用程式的所有視圖共用,該中介層由 web 中介層群組提供。當套用此中介層時,$errors 變數將始終在您的視圖中可用,讓您可以方便地假設 $errors 變數始終定義且可以安全使用。$errors 變數將是 Illuminate\Support\MessageBag 的執行個體。如需更多關於使用此物件的資訊,請查看其文件

因此,在我們的範例中,當驗證失敗時,使用者將被重新導向到控制器的 create 方法,這讓我們可以在視圖中顯示錯誤訊息

<!-- /resources/views/post/create.blade.php -->
 
<h1>Create Post</h1>
 
@if ($errors->any())
<div class="alert alert-danger">
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
 
<!-- Create Post Form -->

自訂錯誤訊息

Laravel 的內建驗證規則各自都有一個錯誤訊息,該訊息位於應用程式的 lang/en/validation.php 檔案中。如果您的應用程式沒有 lang 目錄,您可以指示 Laravel 使用 lang:publish Artisan 命令建立它。

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

此外,您也可以將此檔案複製到其他語言目錄,以翻譯您應用程式語言的訊息。若要深入了解 Laravel 本地化,請參閱完整的本地化文件

exclamation - Laravel 框架

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

XHR 請求和驗證

在此範例中,我們使用傳統表單將資料傳送到應用程式。但是,許多應用程式會接收來自 JavaScript 驅動前端的 XHR 請求。在 XHR 請求期間使用 validate 方法時,Laravel 不會產生重新導向回應。相反地,Laravel 會產生一個包含所有驗證錯誤的 JSON 回應。此 JSON 回應會以 422 HTTP 狀態碼傳送。

@error 指令

您可以使用 @error Blade 指令快速判斷給定屬性是否存在驗證錯誤訊息。在 @error 指令中,您可以輸出 $message 變數來顯示錯誤訊息。

<!-- /resources/views/post/create.blade.php -->
 
<label for="title">Post Title</label>
 
<input
id="title"
type="text"
name="title"
class="@error('title') is-invalid @enderror"
/>
 
@error('title')
<div class="alert alert-danger">{{ $message }}</div>
@enderror

如果您使用具名錯誤包,您可以將錯誤包的名稱作為第二個參數傳遞給 @error 指令。

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

重新填寫表單

當 Laravel 因為驗證錯誤而產生重新導向回應時,框架會自動將所有請求的輸入快閃到 session。這樣做的目的是為了讓您可以在下一個請求期間方便地存取輸入,並重新填寫使用者嘗試提交的表單。

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

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

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

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

關於選填欄位的注意事項

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

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

在此範例中,我們指定 publish_at 欄位可以是 null 或有效的日期表示。如果未將 nullable 修飾符新增至規則定義,驗證器會將 null 視為無效日期。

驗證錯誤回應格式

當您的應用程式拋出 Illuminate\Validation\ValidationException 例外,並且傳入的 HTTP 請求預期收到 JSON 回應時,Laravel 會自動為您格式化錯誤訊息,並傳回 422 Unprocessable Entity HTTP 回應。

下方您可以查看驗證錯誤的 JSON 回應格式範例。請注意,巢狀錯誤索引鍵會被展平為「點」符號格式。

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

表單請求驗證

建立表單請求

對於更複雜的驗證情境,您可能希望建立「表單請求」。表單請求是自訂請求類別,封裝了它們自己的驗證和授權邏輯。若要建立表單請求類別,您可以使用 make:request Artisan CLI 指令。

php artisan make:request StorePostRequest

產生的表單請求類別會放置在 app/Http/Requests 目錄中。如果此目錄不存在,則在您執行 make:request 指令時會建立它。Laravel 產生的每個表單請求都有兩個方法:authorizerules

正如您可能猜到的,authorize 方法負責判斷目前經過驗證的使用者是否可以執行請求所代表的動作,而 rules 方法則會傳回應套用於請求資料的驗證規則。

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

您可以在 rules 方法的簽章中輸入您需要的任何相依性。它們會透過 Laravel 服務容器自動解析。

那麼,驗證規則如何評估呢?您只需要在控制器方法上類型提示請求即可。傳入的表單請求會在呼叫控制器方法之前進行驗證,這表示您不需要讓控制器充滿任何驗證邏輯。

/**
* Store a new blog post.
*/
public function store(StorePostRequest $request): RedirectResponse
{
// The incoming request is valid...
 
// Retrieve the validated input data...
$validated = $request->validated();
 
// Retrieve a portion of the validated input data...
$validated = $request->safe()->only(['name', 'email']);
$validated = $request->safe()->except(['name', 'email']);
 
// Store the blog post...
 
return redirect('/posts');
}

如果驗證失敗,將會產生重新導向回應,將使用者送回他們先前的位置。錯誤也會快閃到 session,以便它們可供顯示。如果請求是 XHR 請求,則會傳回具有 422 狀態碼的 HTTP 回應給使用者,其中包含驗證錯誤的 JSON 表示

lightbulb - Laravel 框架

需要將即時表單請求驗證新增至您 Inertia 驅動的 Laravel 前端嗎?請查看Laravel Precognition

執行額外驗證

有時候您需要在初始驗證完成後執行額外的驗證。您可以使用表單請求的 after 方法來完成此操作。

after 方法應傳回一個可呼叫或閉包的陣列,這些可呼叫或閉包將在驗證完成後被呼叫。給定的可呼叫將接收 Illuminate\Validation\Validator 實例,讓您在必要時引發額外的錯誤訊息。

use Illuminate\Validation\Validator;
 
/**
* Get the "after" validation callables for the request.
*/
public function after(): array
{
return [
function (Validator $validator) {
if ($this->somethingElseIsInvalid()) {
$validator->errors()->add(
'field',
'Something is wrong with this field!'
);
}
}
];
}

如前所述,after 方法傳回的陣列也可以包含可呼叫的類別。這些類別的 __invoke 方法將會收到 Illuminate\Validation\Validator 實例。

use App\Validation\ValidateShippingTime;
use App\Validation\ValidateUserStatus;
use Illuminate\Validation\Validator;
 
/**
* Get the "after" validation callables for the request.
*/
public function after(): array
{
return [
new ValidateUserStatus,
new ValidateShippingTime,
function (Validator $validator) {
//
}
];
}

在第一個驗證失敗時停止

透過將 stopOnFirstFailure 屬性新增至您的請求類別,您可以通知驗證器,在發生單一驗證失敗後,它應該停止驗證所有屬性。

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

自訂重新導向位置

如先前所述,當表單請求驗證失敗時,將會產生重新導向回應,將使用者送回他們先前的位置。不過,您可以自由自訂此行為。若要這樣做,請在您的表單請求上定義 $redirect 屬性。

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

或者,如果您想要將使用者重新導向到具名路由,您可以改為定義 $redirectRoute 屬性。

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

授權表單請求

表單請求類別也包含 authorize 方法。在此方法中,您可以判斷經過驗證的使用者實際上是否具有更新給定資源的權限。例如,您可以判斷使用者是否實際上擁有他們嘗試更新的部落格評論。最有可能的是,您會在此方法中與您的授權閘道和原則互動。

use App\Models\Comment;
 
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
$comment = Comment::find($this->route('comment'));
 
return $comment && $this->user()->can('update', $comment);
}

由於所有表單請求都會擴展基礎 Laravel 請求類別,因此我們可以使用 user 方法來存取目前經過驗證的使用者。此外,請注意上方範例中對 route 方法的呼叫。此方法可讓您存取在被呼叫路由上定義的 URI 參數,例如下方範例中的 {comment} 參數。

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

因此,如果您的應用程式正在利用路由模型綁定,則可以透過將已解析的模型作為請求的屬性存取,使您的程式碼更簡潔。

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

如果 authorize 方法傳回 false,則會自動傳回具有 403 狀態碼的 HTTP 回應,並且不會執行您的控制器方法。

如果您計劃在應用程式的其他部分處理請求的授權邏輯,您可以完全移除 authorize 方法,或僅傳回 true

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

您可以在 authorize 方法的簽章中輸入您需要的任何相依性。它們會透過 Laravel 服務容器自動解析。

自訂錯誤訊息

您可以透過覆寫 messages 方法來自訂表單請求使用的錯誤訊息。此方法應傳回屬性/規則對及其對應的錯誤訊息的陣列。

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

自訂驗證屬性

許多 Laravel 的內建驗證規則錯誤訊息都包含 :attribute 佔位符。如果您希望驗證訊息的 :attribute 佔位符由自訂屬性名稱取代,您可以透過覆寫 attributes 方法來指定自訂名稱。此方法應傳回屬性/名稱對的陣列。

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

準備驗證的輸入

如果您需要在套用驗證規則之前準備或清理請求中的任何資料,您可以使用 prepareForValidation 方法。

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

同樣地,如果您需要在驗證完成後正規化任何請求資料,您可以使用 passedValidation 方法。

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

手動建立驗證器

如果您不想在請求上使用 validate 方法,您可以使用 Validator facade 手動建立驗證器實例。facade 上的 make 方法會產生新的驗證器實例。

<?php
 
namespace App\Http\Controllers;
 
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
 
class PostController extends Controller
{
/**
* Store a new blog post.
*/
public function store(Request $request): RedirectResponse
{
$validator = Validator::make($request->all(), [
'title' => 'required|unique:posts|max:255',
'body' => 'required',
]);
 
if ($validator->fails()) {
return redirect('/post/create')
->withErrors($validator)
->withInput();
}
 
// Retrieve the validated input...
$validated = $validator->validated();
 
// Retrieve a portion of the validated input...
$validated = $validator->safe()->only(['name', 'email']);
$validated = $validator->safe()->except(['name', 'email']);
 
// Store the blog post...
 
return redirect('/posts');
}
}

傳遞給 make 方法的第一個參數是要驗證的資料。第二個參數是應該套用於資料的驗證規則的陣列。

在判斷請求驗證是否失敗後,您可以使用 withErrors 方法將錯誤訊息快閃到 session。使用此方法時,$errors 變數會在重新導向後自動與您的視圖共用,讓您可以輕鬆地將它們顯示回給使用者。withErrors 方法接受驗證器、MessageBag 或 PHP array

在第一次驗證失敗時停止

stopOnFirstFailure 方法會通知驗證器,在發生單一驗證失敗後,它應該停止驗證所有屬性。

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

自動重新導向

如果您想要手動建立驗證器實例,但仍然利用 HTTP 請求的 validate 方法提供的自動重新導向,您可以在現有的驗證器實例上呼叫 validate 方法。如果驗證失敗,使用者將會自動重新導向,或者,在 XHR 請求的情況下,會傳回JSON 回應

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

您可以使用 validateWithBag 方法將錯誤訊息儲存在具名錯誤包中(如果驗證失敗)。

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

命名錯誤袋

如果您在單一頁面上有多個表單,您可能會想要命名包含驗證錯誤的 MessageBag,讓您可以檢索特定表單的錯誤訊息。若要達成此目的,請將名稱作為第二個參數傳遞給 withErrors

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

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

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

自訂錯誤訊息

如果需要,您可以提供驗證器實例應使用的自訂錯誤訊息,而不是 Laravel 提供的預設錯誤訊息。有多種方法可以指定自訂訊息。首先,您可以將自訂訊息作為第三個參數傳遞給 Validator::make 方法。

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

在此範例中,:attribute 佔位符會由正在驗證的欄位的實際名稱取代。您也可以在驗證訊息中使用其他佔位符。例如:

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

為給定屬性指定自訂訊息

有時候您可能只想為特定屬性指定自訂錯誤訊息。您可以使用「點」符號來執行此操作。先指定屬性的名稱,然後指定規則。

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

指定自訂屬性值

Laravel 的許多內建錯誤訊息都包含一個 :attribute 佔位符,它會被替換為正在驗證的欄位或屬性名稱。若要自訂用於替換特定欄位這些佔位符的值,您可以將自訂屬性的陣列作為第四個參數傳遞給 Validator::make 方法。

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

執行額外驗證

有時候您需要在初始驗證完成後執行額外的驗證。您可以使用驗證器的 after 方法來完成此操作。after 方法接受一個閉包或可呼叫的陣列,這些將在驗證完成後被調用。給定的可呼叫對象將接收一個 Illuminate\Validation\Validator 實例,允許您在必要時引發額外的錯誤訊息。

use Illuminate\Support\Facades\Validator;
 
$validator = Validator::make(/* ... */);
 
$validator->after(function ($validator) {
if ($this->somethingElseIsInvalid()) {
$validator->errors()->add(
'field', 'Something is wrong with this field!'
);
}
});
 
if ($validator->fails()) {
// ...
}

如前所述,after 方法也接受一個可呼叫的陣列,如果您的「驗證後」邏輯封裝在可調用的類別中,這將特別方便,這些類別將透過其 __invoke 方法接收一個 Illuminate\Validation\Validator 實例。

use App\Validation\ValidateShippingTime;
use App\Validation\ValidateUserStatus;
 
$validator->after([
new ValidateUserStatus,
new ValidateShippingTime,
function ($validator) {
// ...
},
]);

使用已驗證的輸入

在使用表單請求或手動建立的驗證器實例驗證傳入的請求資料後,您可能希望檢索實際經過驗證的傳入請求資料。這可以透過幾種方式完成。首先,您可以在表單請求或驗證器實例上呼叫 validated 方法。此方法返回已驗證資料的陣列。

$validated = $request->validated();
 
$validated = $validator->validated();

或者,您可以在表單請求或驗證器實例上呼叫 safe 方法。此方法返回 Illuminate\Support\ValidatedInput 的實例。此物件公開 onlyexceptall 方法,以檢索已驗證資料的子集或整個已驗證資料的陣列。

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

此外,Illuminate\Support\ValidatedInput 實例可以被迭代並像陣列一樣存取。

// Validated data may be iterated...
foreach ($request->safe() as $key => $value) {
// ...
}
 
// Validated data may be accessed as an array...
$validated = $request->safe();
 
$email = $validated['email'];

如果您想將其他欄位添加到已驗證的資料中,您可以呼叫 merge 方法。

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

如果您想將已驗證的資料作為 集合 實例檢索,您可以呼叫 collect 方法。

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

使用錯誤訊息

Validator 實例上呼叫 errors 方法後,您將收到一個 Illuminate\Support\MessageBag 實例,它具有多種方便的方法來處理錯誤訊息。自動提供給所有視圖的 $errors 變數也是 MessageBag 類別的實例。

檢索欄位的首個錯誤訊息

若要檢索給定欄位的首個錯誤訊息,請使用 first 方法。

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

檢索欄位的所有錯誤訊息

如果您需要檢索給定欄位的所有訊息的陣列,請使用 get 方法。

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

如果您正在驗證陣列表單欄位,您可以使用 * 字元檢索每個陣列元素的所有訊息。

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

檢索所有欄位的所有錯誤訊息

若要檢索所有欄位的所有訊息的陣列,請使用 all 方法。

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

判斷欄位是否存在訊息

可以使用 has 方法來判斷給定欄位是否存在任何錯誤訊息。

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

在語言檔案中指定自訂訊息

Laravel 的內建驗證規則各自都有一個錯誤訊息,該訊息位於應用程式的 lang/en/validation.php 檔案中。如果您的應用程式沒有 lang 目錄,您可以指示 Laravel 使用 lang:publish Artisan 命令建立它。

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

此外,您也可以將此檔案複製到其他語言目錄,以翻譯您應用程式語言的訊息。若要深入了解 Laravel 本地化,請參閱完整的本地化文件

exclamation - Laravel 框架

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

特定屬性的自訂訊息

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

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

在語言檔案中指定屬性

Laravel 的許多內建錯誤訊息都包含一個 :attribute 佔位符,它會被替換為正在驗證的欄位或屬性名稱。如果您希望驗證訊息的 :attribute 部分被替換為自訂值,您可以在 lang/xx/validation.php 語言檔案的 attributes 陣列中指定自訂屬性名稱。

'attributes' => [
'email' => 'email address',
],
exclamation - Laravel 框架

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

在語言檔案中指定值

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

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

如果此驗證規則失敗,它將產生以下錯誤訊息

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

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

'values' => [
'payment_type' => [
'cc' => 'credit card'
],
],
exclamation - Laravel 框架

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

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

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

可用的驗證規則

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

accepted

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

accepted_if:anotherfield,value,...

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

active_url

驗證下的欄位必須根據 dns_get_record PHP 函數具有有效的 A 或 AAAA 記錄。提供的 URL 的主機名稱會在使用 dns_get_record 之前使用 parse_url PHP 函數提取。

after:date

驗證下的欄位必須是指定日期之後的值。日期將會傳遞到 strtotime PHP 函數中,以便轉換為有效的 DateTime 實例。

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

您可以指定另一個欄位來與日期進行比較,而不是傳遞要由 strtotime 評估的日期字串。

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

after_or_equal:date

驗證下的欄位必須是晚於或等於指定日期的值。如需更多資訊,請參閱 after 規則。

alpha

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

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

'username' => 'alpha:ascii',

alpha_dash

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

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

'username' => 'alpha_dash:ascii',

alpha_num

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

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

'username' => 'alpha_num:ascii',

array

驗證下的欄位必須是 PHP array

當提供額外的值給 array 規則時,輸入陣列中的每個鍵都必須存在於規則提供的數值列表中。在以下範例中,輸入陣列中的 admin 鍵是無效的,因為它未包含在提供給 array 規則的數值列表中。

use Illuminate\Support\Facades\Validator;
 
$input = [
'user' => [
'name' => 'Taylor Otwell',
'username' => 'taylorotwell',
'admin' => true,
],
];
 
Validator::make($input, [
'user' => 'array:name,username',
]);

一般來說,您應該總是明確指定允許出現在陣列中的鍵。

ascii

驗證欄位必須完全是 7 位元的 ASCII 字元。

bail

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

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

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

before:date

驗證欄位的值必須早於給定的日期。日期會傳入 PHP 的 strtotime 函式,以便轉換為有效的 DateTime 實例。此外,如同 after 規則,也可以提供另一個驗證欄位的名稱作為 date 的值。

before_or_equal:date

驗證欄位的值必須早於或等於給定的日期。日期會傳入 PHP 的 strtotime 函式,以便轉換為有效的 DateTime 實例。此外,如同 after 規則,也可以提供另一個驗證欄位的名稱作為 date 的值。

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

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

'password' => 'current_password:api'

date

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

date_equals:date

驗證欄位必須等於給定的日期。日期會傳入 PHP 的 strtotime 函式,以便轉換為有效的 DateTime 實例。

date_format:format,...

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

decimal:min,max

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

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

declined

驗證欄位的值必須是 "no""off"0"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

驗證的檔案必須是符合規則參數所指定維度限制的圖片。

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

可用的限制為:min_widthmax_widthmin_heightmax_heightwidthheightratio

ratio 限制應該表示為寬度除以高度。這可以使用分數(例如 3/2)或浮點數(例如 1.5)來指定。

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

由於此規則需要多個參數,您可以使用 Rule::dimensions 方法來流暢地建構規則。

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

distinct

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

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

預設情況下,Distinct 使用鬆散的變數比較。若要使用嚴格比較,您可以將 strict 參數新增至驗證規則定義。

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

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

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

doesnt_start_with:foo,bar,...

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

doesnt_end_with:foo,bar,...

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

email

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

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

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

  • rfcRFCValidation
  • strictNoRFCWarningsValidation
  • dnsDNSCheckValidation
  • spoofSpoofCheckValidation
  • filterFilterEmailValidation
  • filter_unicodeFilterEmailValidation::unicode()

使用 PHP 的 filter_var 函式的 filter 驗證器,隨附於 Laravel,並且是 Laravel 5.8 版之前 Laravel 的預設電子郵件驗證行為。

exclamation - Laravel 框架

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

ends_with:foo,bar,...

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

enum

Enum 規則是一個基於類別的規則,用於驗證驗證欄位是否包含有效的列舉值。Enum 規則接受列舉的名稱作為其唯一的建構函式參數。當驗證基本型別值時,應將備份列舉提供給 Enum 規則。

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

Enum 規則的 onlyexcept 方法可用於限制哪些列舉案例應被視為有效。

Rule::enum(ServerStatus::class)
->only([ServerStatus::Pending, ServerStatus::Active]);
 
Rule::enum(ServerStatus::class)
->except([ServerStatus::Pending, ServerStatus::Active]);

when 方法可用於有條件地修改 Enum 規則。

use Illuminate\Support\Facades\Auth;
use Illuminate\Validation\Rule;
 
Rule::enum(ServerStatus::class)
->when(
Auth::user()->isAdmin(),
fn ($rule) => $rule->only(...),
fn ($rule) => $rule->only(...),
);

exclude

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

exclude_if:anotherfield,value

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

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

use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;
 
Validator::make($request->all(), [
'role_id' => Rule::excludeIf($request->user()->is_admin),
]);
 
Validator::make($request->all(), [
'role_id' => Rule::excludeIf(fn () => $request->user()->is_admin),
]);

exclude_unless:anotherfield,value

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

exclude_with:anotherfield

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

exclude_without:anotherfield

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

exists:table,column

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

Exists 規則的基本用法

'state' => 'exists:states'

如果未指定 column 選項,將會使用欄位名稱。因此,在此情況下,該規則將驗證 states 資料庫表格是否包含具有符合請求的 state 屬性值的 state 欄位值的記錄。

指定自訂欄位名稱

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

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

有時,您可能需要指定用於 exists 查詢的特定資料庫連線。您可以將連線名稱加在表格名稱之前來完成此操作。

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

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

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

如果您想要自訂驗證規則執行的查詢,可以使用 Rule 類別來流暢地定義規則。在此範例中,我們還會將驗證規則指定為陣列,而不是使用 | 字元來分隔它們。

use Illuminate\Database\Query\Builder;
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;
 
Validator::make($data, [
'email' => [
'required',
Rule::exists('staff')->where(function (Builder $query) {
$query->where('account_id', 1);
}),
],
]);

您可以透過將欄位名稱作為第二個參數提供給 exists 方法,明確指定 Rule::exists 方法產生的 exists 規則應使用的資料庫欄位名稱。

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

extensions:foo,bar,...

驗證的檔案必須具有與所列擴充功能相對應的使用者指定擴充功能。

'photo' => ['required', 'extensions:jpg,png'],
exclamation - Laravel 框架

您永遠不應僅僅依賴驗證檔案的使用者指定擴充功能。此規則通常應始終與 mimesmimetypes 規則一起使用。

file

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

filled

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

gt:field

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

gte:field

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

hex_color

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

image

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

in:foo,bar,...

驗證的欄位必須包含在給定的值列表中。由於此規則通常需要您使用 implode 函數處理陣列,因此可以使用 Rule::in 方法來流暢地建構此規則。

use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;
 
Validator::make($data, [
'zones' => [
'required',
Rule::in(['first-zone', 'second-zone']),
],
]);

in 規則與 array 規則結合使用時,輸入陣列中的每個值都必須存在於提供給 in 規則的值列表中。在以下範例中,輸入陣列中的 LAS 機場代碼是無效的,因為它未包含在提供給 in 規則的機場列表中。

use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;
 
$input = [
'airports' => ['NYC', 'LAS'],
];
 
Validator::make($input, [
'airports' => [
'required',
'array',
],
'airports.*' => Rule::in(['NYC', 'LIT']),
]);

in_array:anotherfield.*

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

integer

驗證的欄位必須是一個整數。

exclamation - Laravel 框架

此驗證規則不會驗證輸入是否為「整數」變數類型,只會驗證輸入是否為 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 類型之一。

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

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

mimes:foo,bar,...

驗證的檔案必須具有與列出的副檔名之一對應的 MIME 類型。

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

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

not_regex:pattern

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

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

exclamation - Laravel 框架

當使用 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 以指示是否應禁止驗證的欄位。

use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;
 
Validator::make($request->all(), [
'role_id' => Rule::prohibitedIf($request->user()->is_admin),
]);
 
Validator::make($request->all(), [
'role_id' => Rule::prohibitedIf(fn () => $request->user()->is_admin),
]);

prohibited_unless:anotherfield,value,...

除非 anotherfield 欄位等於任何 value,否則驗證的欄位必須不存在或為空。如果一個欄位符合以下條件之一,則該欄位為「空」。

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

prohibits:anotherfield,...

如果驗證的欄位不是不存在或為空,則 anotherfield 中的所有欄位都必須不存在或為空。如果一個欄位符合以下條件之一,則該欄位為「空」。

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

regex:pattern

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

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

exclamation - Laravel 框架

當使用 regex / not_regex 模式時,可能需要使用陣列而不是 | 定界符來指定規則,特別是當正規表示式包含 | 字元時。

required

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

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

required_if:anotherfield,value,...

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

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

use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;
 
Validator::make($request->all(), [
'role_id' => Rule::requiredIf($request->user()->is_admin),
]);
 
Validator::make($request->all(), [
'role_id' => Rule::requiredIf(fn () => $request->user()->is_admin),
]);

required_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 為單位)。讓我們看一些範例

// Validate that a string is exactly 12 characters long...
'title' => 'size:12';
 
// Validate that a provided integer equals 10...
'seats' => 'integer|size:10';
 
// Validate that an array has exactly 5 elements...
'tags' => 'array|size:5';
 
// Validate that an uploaded file is exactly 512 kilobytes...
'image' => 'file|size:512';

starts_with:foo,bar,...

驗證的欄位必須以給定值之一開始。

string

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

timezone

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

DateTimeZone::listIdentifiers 方法接受的引數也可以用於此驗證規則。

'timezone' => 'required|timezone:all';
 
'timezone' => 'required|timezone:Africa';
 
'timezone' => 'required|timezone:per_country,US';

unique:資料表,欄位

驗證的欄位在指定的資料庫資料表中必須不存在。

指定自訂資料表/欄位名稱

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

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

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

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

指定自訂資料庫連線

有時,您可能需要為驗證器進行的資料庫查詢設定自訂連線。為此,您可以將連線名稱加在資料表名稱前面。

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

強制唯一規則忽略給定的 ID

有時,您可能希望在唯一性驗證期間忽略給定的 ID。例如,考慮一個包含使用者姓名、電子郵件地址和位置的「更新個人資料」畫面。您可能需要驗證電子郵件地址是否唯一。但是,如果使用者僅更改姓名欄位而不是電子郵件欄位,您不希望因為使用者已經擁有該電子郵件地址而引發驗證錯誤。

為了指示驗證器忽略使用者的 ID,我們將使用 Rule 類別以流暢的方式定義規則。在此範例中,我們也會將驗證規則指定為陣列,而不是使用 | 字元來分隔規則。

use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;
 
Validator::make($data, [
'email' => [
'required',
Rule::unique('users')->ignore($user->id),
],
]);
exclamation - Laravel 框架

您不應將任何使用者控制的請求輸入傳遞到 ignore 方法中。相反地,您應該只傳遞系統產生的唯一 ID,例如來自 Eloquent 模型實例的自動遞增 ID 或 UUID。否則,您的應用程式將容易受到 SQL 注入攻擊。

除了將模型鍵的值傳遞給 ignore 方法之外,您也可以傳遞整個模型實例。Laravel 將自動從模型中提取鍵。

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

如果您的資料表使用 id 以外的主鍵欄位名稱,您可以在呼叫 ignore 方法時指定欄位的名稱。

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

預設情況下,unique 規則將檢查與要驗證的屬性名稱相符的欄位的唯一性。但是,您可以將不同的欄位名稱作為 unique 方法的第二個引數傳遞。

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

新增額外的 Where 子句

您可以使用 where 方法自訂查詢來指定額外的查詢條件。例如,讓我們新增一個查詢條件,將查詢範圍限定為僅搜尋 account_id 欄位值為 1 的記錄。

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

uppercase

驗證的欄位必須為大寫。

url

驗證的欄位必須為有效的 URL。

如果您想指定應視為有效的 URL 協定,您可以將協定作為驗證規則參數傳遞。

'url' => 'url:http,https',
 
'game' => 'url:minecraft,steam',

ulid

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

uuid

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

有條件地新增規則

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

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

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

或者,您可以使用 exclude_unless 規則,除非另一個欄位具有給定值,否則不驗證給定的欄位。

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

當存在時驗證

在某些情況下,您可能希望在要驗證的資料中存在某個欄位時,才對其執行驗證檢查。若要快速實現此目的,請將 sometimes 規則新增至規則清單中。

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

在上面的範例中,只有當 email 欄位存在於 $data 陣列中時,才會驗證該欄位。

lightbulb - Laravel 框架

如果您嘗試驗證一個應該始終存在但可能為空的欄位,請查看關於選用欄位的註解

複雜條件驗證

有時,您可能希望根據更複雜的條件邏輯新增驗證規則。例如,您可能希望僅在另一個欄位的值大於 100 時才需要給定欄位。或者,您可能需要兩個欄位僅在另一個欄位存在時才具有給定值。新增這些驗證規則不必很麻煩。首先,使用永遠不變的靜態規則建立 Validator 實例。

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

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

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

傳遞給 sometimes 方法的第一個引數是要有條件驗證的欄位名稱。第二個引數是要新增的規則清單。如果作為第三個引數傳遞的閉包傳回 true,則會新增規則。此方法可以輕鬆建立複雜的條件驗證。您甚至可以一次新增多個欄位的條件驗證。

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

傳遞到閉包的 $input 參數將是 Illuminate\Support\Fluent 的實例,並且可以用於存取正在驗證的輸入和檔案。

複雜條件陣列驗證

有時,您可能希望根據同一個巢狀陣列中您不知道索引的另一個欄位來驗證欄位。在這種情況下,您可以允許您的閉包接收第二個引數,該引數將是要驗證的陣列中的目前個別項目。

$input = [
'channels' => [
[
'type' => 'email',
'address' => '[email protected]',
],
[
'type' => 'url',
'address' => 'https://example.com',
],
],
];
 
$validator->sometimes('channels.*.address', 'email', function (Fluent $input, Fluent $item) {
return $item->type === 'email';
});
 
$validator->sometimes('channels.*.address', 'url', function (Fluent $input, Fluent $item) {
return $item->type !== 'email';
});

與傳遞到閉包的 $input 參數一樣,當屬性資料為陣列時,$item 參數是 Illuminate\Support\Fluent 的實例;否則,它是一個字串。

驗證陣列

array 驗證規則文件中所述,array 規則接受允許的陣列鍵清單。如果陣列中存在任何其他鍵,驗證將會失敗。

use Illuminate\Support\Facades\Validator;
 
$input = [
'user' => [
'name' => 'Taylor Otwell',
'username' => 'taylorotwell',
'admin' => true,
],
];
 
Validator::make($input, [
'user' => 'array:name,username',
]);

一般來說,您應該始終指定允許存在於陣列中的陣列鍵。否則,驗證器的 validatevalidated 方法將傳回所有經過驗證的資料,包括陣列及其所有鍵,即使這些鍵沒有被其他巢狀陣列驗證規則驗證。

驗證巢狀陣列輸入

驗證巢狀陣列型表單輸入欄位不必很麻煩。您可以使用「點符號」來驗證陣列中的屬性。例如,如果傳入的 HTTP 請求包含 photos[profile] 欄位,您可以像這樣驗證它。

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

您也可以驗證陣列的每個元素。例如,若要驗證給定陣列輸入欄位中的每個電子郵件是否唯一,您可以執行以下操作。

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

同樣地,您也可以在語言檔中指定自訂驗證訊息時使用 * 字元,讓您可以輕鬆地為陣列型欄位使用單一驗證訊息。

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

存取巢狀陣列資料

有時,您可能需要在將驗證規則指派給屬性時存取給定巢狀陣列元素的值。您可以使用 Rule::forEach 方法來實現此目的。forEach 方法接受一個閉包,該閉包將針對正在驗證的陣列屬性的每個迭代調用,並且將接收屬性的值和明確、完全展開的屬性名稱。閉包應傳回要指派給陣列元素的規則陣列。

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

錯誤訊息索引和位置

在驗證陣列時,您可能希望在應用程式顯示的錯誤訊息中引用驗證失敗的特定項目的索引或位置。為此,您可以在自訂驗證訊息中包含 :index (從 0 開始) 和 :position (從 1 開始) 預留位置。

use Illuminate\Support\Facades\Validator;
 
$input = [
'photos' => [
[
'name' => 'BeachVacation.jpg',
'description' => 'A photo of my beach vacation!',
],
[
'name' => 'GrandCanyon.jpg',
'description' => '',
],
],
];
 
Validator::validate($input, [
'photos.*.description' => 'required',
], [
'photos.*.description.required' => 'Please describe photo #:position.',
]);

以上面的範例為例,驗證將會失敗,並且使用者將會收到以下錯誤訊息:「請描述照片 #2。」

如有必要,您可以透過 second-indexsecond-positionthird-indexthird-position 等來引用更深層的巢狀索引和位置。

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

驗證檔案

Laravel 提供各種驗證規則,可用於驗證上傳的檔案,例如 mimesimageminmax。雖然您可以在驗證檔案時自由地個別指定這些規則,但 Laravel 也提供流暢的檔案驗證規則建構器,您可能會覺得很方便。

use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rules\File;
 
Validator::validate($input, [
'attachment' => [
'required',
File::types(['mp3', 'wav'])
->min(1024)
->max(12 * 1024),
],
]);

如果您的應用程式接受使用者上傳的影像,您可以使用 File 規則的 image 建構函式方法來指示上傳的檔案應為影像。此外,dimensions 規則可用於限制影像的尺寸。

use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;
use Illuminate\Validation\Rules\File;
 
Validator::validate($input, [
'photo' => [
'required',
File::image()
->min(1024)
->max(12 * 1024)
->dimensions(Rule::dimensions()->maxWidth(1000)->maxHeight(500)),
],
]);
lightbulb - Laravel 框架

關於驗證影像尺寸的更多資訊,請參閱尺寸規則文件

檔案大小

為了方便起見,最小和最大檔案大小可以指定為帶有尾碼的字串,表示檔案大小單位。支援 kbmbgbtb 尾碼。

File::image()
->min('1kb')
->max('10mb')

檔案類型

即使您在調用 types 方法時只需要指定副檔名,此方法實際上會透過讀取檔案的內容並猜測其 MIME 類型來驗證檔案的 MIME 類型。MIME 類型及其對應副檔名的完整清單可以在以下位置找到。

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

驗證密碼

為了確保密碼具有足夠的複雜程度,您可以使用 Laravel 的 Password 規則物件。

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

Password 規則物件可讓您輕鬆自訂應用程式的密碼複雜度要求,例如指定密碼至少需要一個字母、數字、符號或大小寫混合的字元。

// Require at least 8 characters...
Password::min(8)
 
// Require at least one letter...
Password::min(8)->letters()
 
// Require at least one uppercase and one lowercase letter...
Password::min(8)->mixedCase()
 
// Require at least one number...
Password::min(8)->numbers()
 
// Require at least one symbol...
Password::min(8)->symbols()

此外,您可以使用 uncompromised 方法來確保密碼沒有在公開的密碼資料外洩中遭到洩漏。

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

在內部,Password 規則物件使用k-匿名模型,透過 haveibeenpwned.com 服務來判斷密碼是否洩漏,而不會犧牲使用者的隱私或安全性。

預設情況下,如果密碼在資料外洩中至少出現一次,則會被視為洩漏。您可以使用 uncompromised 方法的第一個引數來自訂此閾值。

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

當然,您可以鏈結上面範例中的所有方法。

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

定義預設密碼規則

您可能會發現在應用程式的單一位置指定密碼的預設驗證規則會很方便。您可以使用 Password::defaults 方法輕鬆完成此操作,該方法接受一個閉包。傳遞給 defaults 方法的閉包應返回 Password 規則的預設配置。通常,defaults 規則應該在您的應用程式的其中一個服務提供者的 boot 方法中調用。

use Illuminate\Validation\Rules\Password;
 
/**
* Bootstrap any application services.
*/
public function boot(): void
{
Password::defaults(function () {
$rule = Password::min(8);
 
return $this->app->isProduction()
? $rule->mixedCase()->uncompromised()
: $rule;
});
}

然後,當您想要將預設規則應用於正在進行驗證的特定密碼時,您可以調用不帶任何參數的 defaults 方法。

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

有時,您可能想要將其他驗證規則附加到您的預設密碼驗證規則。您可以使用 rules 方法來完成此操作。

use App\Rules\ZxcvbnRule;
 
Password::defaults(function () {
$rule = Password::min(8)->rules([new ZxcvbnRule]);
 
// ...
});

自訂驗證規則

使用規則物件

Laravel 提供了各種有用的驗證規則;但是,您可能希望指定一些您自己的規則。註冊自訂驗證規則的一種方法是使用規則物件。要產生新的規則物件,您可以使用 make:rule Artisan 命令。讓我們使用此命令來產生一個驗證字串是否為大寫的規則。Laravel 會將新規則放置在 app/Rules 目錄中。如果此目錄不存在,Laravel 會在您執行 Artisan 命令以建立規則時建立它。

php artisan make:rule Uppercase

建立規則後,我們就可以定義其行為。規則物件包含一個單一方法:validate。此方法接收屬性名稱、其值和一個回呼,該回呼應在驗證失敗時使用驗證錯誤訊息調用。

<?php
 
namespace App\Rules;
 
use Closure;
use Illuminate\Contracts\Validation\ValidationRule;
 
class Uppercase implements ValidationRule
{
/**
* Run the validation rule.
*/
public function validate(string $attribute, mixed $value, Closure $fail): void
{
if (strtoupper($value) !== $value) {
$fail('The :attribute must be uppercase.');
}
}
}

定義規則後,您可以通過傳遞規則物件的實例以及其他驗證規則來將其附加到驗證器。

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

翻譯驗證訊息

除了向 $fail 閉包提供文字錯誤訊息之外,您還可以提供翻譯字串鍵,並指示 Laravel 翻譯錯誤訊息。

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

如有必要,您可以將佔位符替換和首選語言作為 translate 方法的第一個和第二個參數提供。

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

存取其他資料

如果您的自訂驗證規則類別需要存取所有其他正在驗證的資料,則您的規則類別可以實作 Illuminate\Contracts\Validation\DataAwareRule 介面。此介面要求您的類別定義一個 setData 方法。此方法將由 Laravel 自動調用(在驗證進行之前),並帶有正在驗證的所有資料。

<?php
 
namespace App\Rules;
 
use Illuminate\Contracts\Validation\DataAwareRule;
use Illuminate\Contracts\Validation\ValidationRule;
 
class Uppercase implements DataAwareRule, ValidationRule
{
/**
* All of the data under validation.
*
* @var array<string, mixed>
*/
protected $data = [];
 
// ...
 
/**
* Set the data under validation.
*
* @param array<string, mixed> $data
*/
public function setData(array $data): static
{
$this->data = $data;
 
return $this;
}
}

或者,如果您的驗證規則需要存取執行驗證的驗證器實例,則您可以實作 ValidatorAwareRule 介面。

<?php
 
namespace App\Rules;
 
use Illuminate\Contracts\Validation\ValidationRule;
use Illuminate\Contracts\Validation\ValidatorAwareRule;
use Illuminate\Validation\Validator;
 
class Uppercase implements ValidationRule, ValidatorAwareRule
{
/**
* The validator instance.
*
* @var \Illuminate\Validation\Validator
*/
protected $validator;
 
// ...
 
/**
* Set the current validator.
*/
public function setValidator(Validator $validator): static
{
$this->validator = $validator;
 
return $this;
}
}

使用閉包

如果您只需要在應用程式中使用一次自訂規則的功能,則可以使用閉包而不是規則物件。閉包接收屬性的名稱、屬性的值和一個 $fail 回呼,如果驗證失敗,則應調用該回呼。

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

隱含規則

預設情況下,當正在驗證的屬性不存在或包含空字串時,不會執行包括自訂規則在內的一般驗證規則。例如,unique 規則將不會針對空字串執行。

use Illuminate\Support\Facades\Validator;
 
$rules = ['name' => 'unique:users,name'];
 
$input = ['name' => ''];
 
Validator::make($input, $rules)->passes(); // true

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

php artisan make:rule Uppercase --implicit
exclamation - Laravel 框架

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