コンテンツへスキップ

バリデーション

はじめに

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はユーザーを前の場所に自動的にリダイレクトします。さらに、すべてのバリデーションエラーとリクエスト入力は、セッションに自動的にフラッシュされます

`Illuminate\View\Middleware\ShareErrorsFromSession`ミドルウェア(`web`ミドルウェアグループによって提供される)によって、`$errors`変数はアプリケーションのすべてのビューで共有されます。このミドルウェアが適用されると、`$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ディレクトリがない場合は、lang:publish Artisanコマンドを使用して作成するように指示できます。

lang/en/validation.phpファイル内には、各検証ルールの翻訳エントリがあります。アプリケーションのニーズに応じて、これらのメッセージを変更または修正できます。

さらに、このファイルを別の言語ディレクトリにコピーして、アプリケーションの言語のメッセージを翻訳できます。Laravelのローカライズの詳細については、完全なローカライズドキュメントを参照してください。

exclamation

デフォルトでは、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ディレクティブの第2引数としてエラーバッグの名前を渡すことができます。

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

フォームの再入力

検証エラーのためにLaravelがリダイレクトレスポンスを生成する場合、フレームワークはリクエストのすべての入力をセッションに自動的にフラッシュします。これは、次のリクエスト中に入力を簡単にアクセスして、ユーザーが送信しようとしたフォームを再入力できるようにするためです。

前のリクエストからフラッシュされた入力を取得するには、Illuminate\Http\Requestのインスタンスでoldメソッドを呼び出します。oldメソッドは、セッションから以前にフラッシュされた入力データを取得します。

$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によって生成された各フォームリクエストには、authorizeメソッドとrulesメソッドの2つのメソッドがあります。

予想通り、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

rulesメソッドのシグネチャ内で必要な依存関係を型ヒントできます。それらはLaravel サービスコンテナによって自動的に解決されます。

では、検証ルールはどう評価されるのでしょうか?必要なのは、コントローラーメソッドでリクエストを型ヒントすることだけです。コントローラーメソッドが呼び出される前に着信フォームリクエストが検証されるため、コントローラーに検証ロジックを追加する必要はありません。

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

検証に失敗すると、ユーザーを前の場所に送り返すリダイレクトレスポンスが生成されます。エラーもセッションにフラッシュされるため、表示に使用できます。リクエストがXHRリクエストだった場合は、検証エラーのJSON表現を含む422ステータスコードのHTTPレスポンスがユーザーに返されます。

lightbulb

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

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 ファサードを使用してバリデータインスタンスを手動で作成できます。ファサードの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メソッドに渡される最初の引数は、検証対象のデータです。2番目の引数は、データに適用する必要がある検証ルールの配列です。

リクエストの検証が失敗したかどうかを判断した後、withErrorsメソッドを使用してエラーメッセージをセッションにフラッシュできます。このメソッドを使用すると、リダイレクト後、$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の第2引数として名前を渡します。

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

その後、`$errors` 変数から名前付きの `MessageBag` インスタンスにアクセスできます。

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

エラーメッセージのカスタマイズ

必要に応じて、Laravel が提供するデフォルトのエラーメッセージの代わりに、バリデータインスタンスが使用するカスタムエラーメッセージを指定できます。カスタムメッセージを指定するにはいくつかの方法があります。まず、`Validator::make` メソッドの第3引数としてカスタムメッセージを渡すことができます。

$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` メソッドの第4引数として渡すことができます。

$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` のインスタンスを返します。このオブジェクトは、検証されたデータのサブセットまたは検証されたデータの配列全体を取得するための `only`、`except`、`all` メソッドを公開しています。

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

さらに、`Illuminate\Support\ValidatedInput` インスタンスは、配列のように反復処理してアクセスできます。

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

検証済みデータに追加のフィールドを追加する場合は、`merge` メソッドを呼び出すことができます。

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

検証済みデータを コレクション インスタンスとして取得する場合は、`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ディレクトリがない場合は、lang:publish Artisanコマンドを使用して作成するように指示できます。

lang/en/validation.phpファイル内には、各検証ルールの翻訳エントリがあります。アプリケーションのニーズに応じて、これらのメッセージを変更または修正できます。

さらに、このファイルを別の言語ディレクトリにコピーして、アプリケーションの言語のメッセージを翻訳できます。Laravelのローカライズの詳細については、完全なローカライズドキュメントを参照してください。

exclamation

デフォルトでは、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アプリケーションのスケルトンには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.

`cc` を支払いタイプ値として表示する代わりに、`lang/xx/validation.php` 言語ファイルで `values` 配列を定義することにより、よりユーザーフレンドリーな値表現を指定できます。

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

デフォルトでは、Laravelアプリケーションのスケルトンにはlangディレクトリが含まれていません。Laravelの言語ファイルをカスタマイズする場合は、lang:publish Artisanコマンドを使用して公開できます。

この値を定義した後、検証ルールは次のエラーメッセージを生成します。

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

利用可能なバリデーションルール

以下は、使用可能なすべての検証ルールとその機能の一覧です。

承認済み 条件付き承認 有効なURL 後(日付) 以降(日付) 英字 英数字とハイフン 英数字 配列 ASCII文字 早期終了 前(日付) 以前(日付) 範囲内 ブール値 確認済み 含まれる 現在のパスワード 日付 日付一致 日付形式 小数 拒否済み 条件付き拒否 異なる 桁数 桁数範囲 寸法(画像ファイル) 重複なし で始まらない で終わらない メールアドレス で終わる 列挙型 除外 条件付き除外 条件付き除外(否定) 同時除外 同時除外(否定) 存在(データベース) 拡張子 ファイル 入力済み より大きい 以上 16進カラーコード 画像(ファイル) いずれか 配列内 整数 IPアドレス JSON より小さい 以下 リスト 小文字 MACアドレス 最大値 最大桁数 MIMEタイプ MIMEタイプ(拡張子) 最小値 最小桁数 未入力 条件付き未入力 条件付き未入力(否定) 同時未入力 すべて同時未入力 倍数 いずれでもない 正規表現に一致しない NULL許容 数値 入力済み 条件付き入力済み 条件付き入力済み(否定) 同時入力済み すべて同時入力済み 禁止 条件付き禁止 条件付き禁止(否定) 禁止 正規表現 必須 条件付き必須 承認済み時の必須 拒否済み時の必須 条件付き必須(否定) 同時必須 すべて同時必須 同時必須(否定) すべて同時必須(否定) 配列キー必須 同じ サイズ 条件付き検証 で始まる 文字列 タイムゾーン 一意(データベース) 大文字 URL ULID UUID

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 のホスト名は、`parse_url` PHP 関数を使用して抽出され、`dns_get_record` に渡される前に抽出されます。

after:date

検証対象のフィールドは、指定された日付より後の値でなければなりません。日付は、有効な `DateTime` インスタンスに変換するために、`strtotime` PHP 関数に渡されます。

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

`strtotime` で評価される日付文字列を渡す代わりに、日付と比較する別のフィールドを指定できます。

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

after_or_equal:date

検証対象のフィールドは、指定された日付以降の値でなければなりません。詳細については、after ルールを参照してください。

alpha

検証対象のフィールドは、\p{L}\p{M} に含まれるUnicode英字のみで構成されている必要があります。

この検証ルールをASCII範囲( `a-z` と `A-Z` )の文字に制限するには、検証ルールに `ascii` オプションを指定できます。

'username' => 'alpha:ascii',

alpha_dash

検証対象のフィールドは、\p{L}\p{M}\p{N} に含まれるUnicode英数字、およびASCIIハイフン(`-`)とASCIIアンダースコア(`_`)のみで構成されている必要があります。

この検証ルールをASCII範囲( `a-z` と `A-Z` )の文字に制限するには、検証ルールに `ascii` オプションを指定できます。

'username' => 'alpha_dash:ascii',

alpha_num

検証対象のフィールドは、\p{L}\p{M}、および \p{N} に含まれるUnicode英数字のみで構成されている必要があります。

この検証ルールをASCII範囲( `a-z` と `A-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,...

検証対象のフィールドは、指定されたformatのいずれかと一致する必要があります。フィールドの検証には、dateまたはdate_formatどちらか一方を使用し、両方を使用しないでください。この検証ルールは、PHPのDateTimeクラスでサポートされているすべての形式をサポートしています。

decimal:min,max

検証対象のフィールドは数値であり、指定された桁数の小数点以下を含んでいる必要があります。

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

declined

検証対象のフィールドは、"no""off"0"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検証が適用されます。適用できる検証スタイルの完全なリストを以下に示します。

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

PHPのfilter_var関数を使用するfilterバリデータはLaravelに含まれており、Laravel 5.8以前のLaravelのデフォルトのメール検証動作でした。

exclamation

dnsおよびspoofバリデータには、PHPのintl拡張機能が必要です。

ends_with:foo,bar,...

検証対象のフィールドは、指定された値のいずれかで終わる必要があります。

enum

Enumルールは、クラスベースのルールであり、検証対象のフィールドに有効な列挙値が含まれているかどうかを検証します。Enumルールは、コンストラクタ引数として列挙子の名前を受け入れます。プリミティブ値を検証する際には、Enumルールに裏付けとなるEnumを提供する必要があります。

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

Enumルールのonlyメソッドとexceptメソッドを使用して、有効と見なされる列挙ケースを制限できます。

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

検証対象のフィールドは、validateメソッドとvalidatedメソッドによって返されるリクエストデータから除外されます。

exclude_if:anotherfield,value

anotherfieldフィールドがvalueと等しい場合、検証対象のフィールドは、validateメソッドとvalidatedメソッドによって返されるリクエストデータから除外されます。

複雑な条件付き除外ロジックが必要な場合は、Rule::excludeIfメソッドを使用できます。このメソッドは、ブール値またはクロージャを受け入れます。クロージャが指定されている場合、クロージャは、検証対象のフィールドを除外する必要があるかどうかを示すtrueまたはfalseを返す必要があります。

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

exclude_unless:anotherfield,value

anotherfieldフィールドがvalueと等しくない限り、検証対象のフィールドは、validateメソッドとvalidatedメソッドによって返されるリクエストデータから除外されます。valuenullexclude_unless:name,null)の場合、比較フィールドがnullであるか、リクエストデータに比較フィールドが存在しない限り、検証対象のフィールドは除外されます。

exclude_with:anotherfield

anotherfieldフィールドが存在する場合、検証対象のフィールドは、validateメソッドとvalidatedメソッドによって返されるリクエストデータから除外されます。

exclude_without:anotherfield

anotherfieldフィールドが存在しない場合、検証対象のフィールドは、validateメソッドとvalidatedメソッドによって返されるリクエストデータから除外されます。

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

Rule::existsメソッドによって生成されるexistsルールで使用されるデータベース列名を明示的に指定するには、列名をexistsメソッドの2番目の引数として提供します。

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

extensions:foo,bar,...

検証対象のファイルは、リストされている拡張子のいずれかに対応するユーザーが割り当てた拡張子を持っている必要があります。

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

ユーザーが割り当てた拡張子だけでファイルの検証に依存することは決してありません。このルールは、通常、mimesルールまたはmimetypesルールと組み合わせて使用​​する必要があります。

file

検証対象のフィールドは、正常にアップロードされたファイルである必要があります。

filled

検証対象のフィールドは、存在する場合、空であってはいけません。

gt:field

検証対象のフィールドは、指定されたfieldまたはvalueより大きくなければなりません。2つのフィールドは同じ型である必要があります。文字列、数値、配列、ファイルは、sizeルールと同じ規約を使用して評価されます。

gte:field

検証対象のフィールドは、指定されたfieldまたはvalue以上でなければなりません。2つのフィールドは同じ型である必要があります。文字列、数値、配列、ファイルは、sizeルールと同じ規約を使用して評価されます。

hex_color

検証対象のフィールドには、16進数形式で有効なカラー値が含まれている必要があります。

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

この検証ルールは、入力が「整数」変数型であることを検証するのではなく、入力がPHPのFILTER_VALIDATE_INTルールの受け入れられる型であることだけを検証します。入力が数値であることを検証する必要がある場合は、numeric検証ルールと組み合わせてこのルールを使用してください。

ip

検証対象のフィールドは、IPアドレスである必要があります。

ipv4

バリデーション対象のフィールドは、IPv4アドレスでなければなりません。

ipv6

バリデーション対象のフィールドは、IPv6アドレスでなければなりません。

json

バリデーション対象のフィールドは、有効なJSON文字列でなければなりません。

lt:field

バリデーション対象のフィールドは、指定されたfieldより小さくなければなりません。2つのフィールドは同じ型でなければなりません。文字列、数値、配列、ファイルは、sizeルールと同じ規則に従って評価されます。

lte:field

バリデーション対象のフィールドは、指定されたfield以下でなければなりません。2つのフィールドは同じ型でなければなりません。文字列、数値、配列、ファイルは、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バリデーションルールは、ファイル名がphoto.txtであっても、有効なPNGコンテンツを含むファイルを有効なPNG画像と見なします。ユーザーが割り当てたファイルの拡張子を検証する場合は、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

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メソッドを使用できます。このメソッドは、ブール値またはクロージャを受け入れます。クロージャが渡された場合、クロージャは、バリデーション対象のフィールドを禁止するかどうかを示すtrueまたはfalseを返す必要があります。

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

prohibited_unless:anotherfield,value,...

anotherfieldフィールドがvalueのいずれかと等しくない限り、バリデーション対象のフィールドは存在しないか空でなければなりません。フィールドが「空」であるとは、次の基準のいずれかを満たす場合を指します。

  • 値がnullである。
  • 値が空の文字列である。
  • 値が空の配列または空のCountableオブジェクトである。
  • 値が空のパスを持つアップロードされたファイルである。

prohibits:anotherfield,...

バリデーション対象のフィールドが存在しないか空でない場合、anotherfield内のすべてのフィールドは存在しないか空でなければなりません。フィールドが「空」であるとは、次の基準のいずれかを満たす場合を指します。

  • 値がnullである。
  • 値が空の文字列である。
  • 値が空の配列または空のCountableオブジェクトである。
  • 値が空のパスを持つアップロードされたファイルである。

regex:pattern

バリデーション対象のフィールドは、指定された正規表現に一致しなければなりません。

内部的には、このルールはPHPのpreg_match関数を使用します。指定されたパターンは、preg_matchで要求されるのと同じフォーマットに従う必要があり、そのため有効なデリミタも含まれている必要があります。例:'email' => 'regex:/^.+@.+$/i'

exclamation

regex/not_regexパターンを使用する場合は、特に正規表現に|文字が含まれる場合、|デリミタを使用する代わりに配列を使用してルールを指定する必要がある場合があります。

required

バリデーション対象のフィールドは、入力データに存在し、空でなければなりません。フィールドが「空」であるとは、次の基準のいずれかを満たす場合を指します。

  • 値がnullである。
  • 値が空の文字列である。
  • 値が空の配列または空のCountableオブジェクトである。
  • 値がパスを持たないアップロードされたファイルである。

required_if:anotherfield,value,...

anotherfieldフィールドがvalueのいずれかと等しい場合、バリデーション対象のフィールドは存在し、空でなければなりません。

required_ifルールのより複雑な条件を構築する場合は、Rule::requiredIfメソッドを使用できます。このメソッドは、ブール値またはクロージャを受け入れます。クロージャが渡された場合、クロージャは、バリデーション対象のフィールドが必要かどうかを示すtrueまたはfalseを返す必要があります。

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

required_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のいずれかと等しくない限り、バリデーション対象のフィールドは存在し、空でなければなりません。これは、valuenullでない限り、anotherfieldもリクエストデータに存在する必要があることを意味します。valuenullrequired_unless:name,null)の場合、比較フィールドがnullであるか、比較フィールドがリクエストデータに存在しない限り、バリデーション対象のフィールドは必須になります。

required_with:foo,bar,...

他の指定されたフィールドのいずれかが存在し、空でない *場合のみ*、バリデーション対象のフィールドは存在し、空でなければなりません。

required_with_all:foo,bar,...

他の指定されたフィールドのすべてが存在し、空でない *場合のみ*、バリデーション対象のフィールドは存在し、空でなければなりません。

required_without:foo,bar,...

他の指定されたフィールドのいずれかが空であるか存在しない *場合のみ*、バリデーション対象のフィールドは存在し、空でなければなりません。

required_without_all:foo,bar,...

他の指定されたフィールドのすべてが空であるか存在しない *場合のみ*、バリデーション対象のフィールドは存在し、空でなければなりません。

required_array_keys:foo,bar,...

バリデーション対象のフィールドは配列でなければならず、指定されたキーを少なくとも含んでいなければなりません。

same:field

指定されたfieldは、バリデーション対象のフィールドと一致しなければなりません。

size:value

バリデーション対象のフィールドは、指定されたvalueと一致するサイズでなければなりません。文字列データの場合、valueは文字数に対応します。数値データの場合、valueは指定された整数値に対応します(属性にはnumericまたはintegerルールも含まれている必要があります)。配列の場合、sizeは配列のcountに対応します。ファイルの場合、sizeはキロバイト単位のファイルサイズに対応します。いくつかの例を見てみましょう。

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

starts_with:foo,bar,...

バリデーション対象のフィールドは、指定された値のいずれかで始まる必要があります。

string

検証対象のフィールドは文字列である必要があります。フィールドにnullも許可したい場合は、フィールドにnullableルールを割り当てる必要があります。

タイムゾーン

検証対象のフィールドは、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

ユーザーが制御できるリクエスト入力をignoreメソッドに渡すべきではありません。代わりに、自動増分IDやEloquentモデルインスタンスからのUUIDなど、システムが生成した一意のIDのみを渡してください。 そうしないと、アプリケーションがSQLインジェクション攻撃の脆弱性を持つことになります。

ignoreメソッドにモデルキーの値を渡す代わりに、モデルインスタンス全体を渡すこともできます。Laravelはモデルからキーを自動的に抽出します。

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

テーブルがid以外の主キーカラム名を使用している場合、ignoreメソッドを呼び出す際にカラム名を指定できます。

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

デフォルトでは、uniqueルールは検証対象の属性名と一致するカラムの一意性をチェックします。ただし、uniqueメソッドの第2引数として異なるカラム名を渡すことができます。

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

検証対象のフィールドは、有効なUniversally Unique Lexicographically Sortable Identifier (ULID)である必要があります。

uuid

検証対象のフィールドは、有効なRFC 4122(バージョン1、3、4、または5)の universally unique identifier (UUID)である必要があります。

条件付きルール追加

特定の値を持つフィールドの検証スキップ

別のフィールドが特定の値を持つ場合、特定のフィールドを検証しないようにしたい場合があります。これは、exclude_if検証ルールを使用して実現できます。この例では、has_appointmentフィールドの値がfalseの場合、appointment_dateフィールドとdoctor_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

常に存在する可能性のあるが空の可能性のあるフィールドを検証しようとしている場合は、オプションフィールドに関するこの注記を確認してください。

複雑な条件付き検証

より複雑な条件付きロジックに基づいて検証ルールを追加したい場合があります。たとえば、別のフィールドの値が100より大きい場合にのみ、特定のフィールドを必須にすることができます。または、別のフィールドが存在する場合にのみ、2つのフィールドが特定の値を持つ必要があります。これらの検証ルールを追加するのは難しいことではありません。まず、変更されない静的ルールを使用してValidatorインスタンスを作成します。

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

私たちのウェブアプリケーションがゲームコレクター向けであると仮定しましょう。ゲームコレクターが私たちのアプリケーションに登録し、100個以上のゲームを所有している場合、なぜそんなに多くのゲームを所有しているのかを説明してもらいたいでしょう。たとえば、ゲームの転売店を経営している場合や、単にゲームのコレクションが好きである場合があります。この要件を条件付きで追加するには、Validatorインスタンスのsometimesメソッドを使用できます。

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

sometimesメソッドに渡される最初の引数は、条件付きで検証するフィールドの名前です。2番目の引数は、追加するルールのリストです。3番目の引数として渡されたクロージャがtrueを返す場合、ルールが追加されます。このメソッドを使用すると、複雑な条件付き検証を簡単に構築できます。複数のフィールドに条件付き検証を一度に追加することもできます。

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

クロージャに渡される$inputパラメータは、Illuminate\Support\Fluentのインスタンスであり、検証対象の入力とファイルにアクセスするために使用できます。

複雑な条件付き配列検証

インデックスが不明な同じネストされた配列内の別のフィールドに基づいてフィールドを検証したい場合があります。このような状況では、クロージャが2番目の引数を受け取ることを許可できます。2番目の引数は、検証対象の配列内の現在の個々のアイテムになります。

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

一般的に、配列内に存在することを許可する配列キーを常に指定する必要があります。そうしないと、バリデータのvalidateメソッドとvalidatedメソッドは、他のネストされた配列検証ルールによって検証されていないキーも含めて、検証されたデータ全体(配列とそのすべてのキーを含む)を返します。

ネストされた配列入力のバリデーション

ネストされた配列ベースのフォーム入力フィールドの検証は、それほど難しくありません。「ドット表記」を使用して、配列内の属性を検証できます。たとえば、受信した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),
];
}),
]);

エラーメッセージのインデックスと位置

配列を検証する場合、アプリケーションによって表示されるエラーメッセージ内で、検証に失敗した特定のアイテムのインデックスまたは位置を参照したい場合があります。これを実現するには、カスタム検証メッセージ内に:index0から始まる)と:position1から始まる)プレースホルダーを含めることができます。

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

寸法ルールのドキュメントで、画像寸法の検証に関する詳細情報を確認できます。

ファイルサイズ

便宜上、最小および最大ファイルサイズは、ファイルサイズの単位を示すサフィックス付きの文字列として指定できます。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ルールオブジェクトを使用すると、アプリケーションのパスワード複雑性の要件を簡単にカスタマイズできます。たとえば、パスワードに少なくとも1つの英字、数字、記号、または大小混合の文字を含める必要があることを指定できます。

// 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サービスを介してパスワードが漏洩したかどうかを判断します。

デフォルトでは、パスワードがデータ漏洩に少なくとも1回表示されると、侵害されたと見なされます。この閾値は、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ルールは、アプリケーションのサービスプロバイダの1つの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はさまざまな便利な検証ルールを提供していますが、独自のルールを指定したい場合があります。カスタム検証ルールを登録する1つの方法は、ルールオブジェクトを使用することです。新しいルールオブジェクトを生成するには、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メソッドの最初の引数と2番目の引数として提供できます。

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

クロージャの使用

アプリケーション全体でカスタムルールの機能を1回だけ必要とする場合は、ルールオブジェクトの代わりにクロージャを使用できます。クロージャは、属性名、属性の値、および検証に失敗した場合に呼び出される必要がある$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

「暗黙的」なルールは、属性が必要であることを暗示するだけです。実際に不足または空の属性を無効にするかどうかは、あなた次第です。