バリデーション
- イントロダクション
- バリデーションクイックスタート
- フォームリクエストバリデーション
- バリデータの手動作成
- バリデーション済み入力の操作
- エラーメッセージの操作
- 利用可能なバリデーションルール
- ルールの条件付き追加
- 配列のバリデーション
- ファイルのバリデーション
- パスワードのバリデーション
- カスタムバリデーションルール
イントロダクション
Laravelは、アプリケーションの受信データをバリデーションするための、いくつかの異なるアプローチを提供しています。すべての受信HTTPリクエストで使用可能なvalidateメソッドを使用するのが最も一般的です。しかし、他のバリデーションのアプローチについても説明します。
Laravelには、データに適用できる便利なバリデーションルールが多種多様に含まれており、指定したデータベーステーブル内で値が一意であるかどうかをバリデーションする機能さえ提供しています。Laravelのすべてのバリデーション機能に精通できるように、これらの各バリデーションルールについて詳しく説明します。
バリデーションクイックスタート
Laravelの強力なバリデーション機能を学ぶために、フォームをバリデーションし、ユーザーにエラーメッセージを表示する完全な例を見ていきましょう。この概要を読むことで、Laravelを使用して受信リクエストデータをバリデーションする方法について、優れた全般的な理解を得ることができるでしょう。
ルートの定義
まず、routes/web.phpファイルに以下のルートが定義されていると仮定しましょう。
1use App\Http\Controllers\PostController;2 3Route::get('/post/create', [PostController::class, 'create']);4Route::post('/post', [PostController::class, 'store']);
GETルートは、ユーザーが新しいブログ投稿を作成するためのフォームを表示し、POSTルートは、新しいブログ投稿をデータベースに保存します。
コントローラの作成
次に、これらのルートへの受信リクエストを処理する簡単なコントローラを見てみましょう。今のところstoreメソッドは空のままにしておきます。
1<?php 2 3namespace App\Http\Controllers; 4 5use Illuminate\Http\RedirectResponse; 6use Illuminate\Http\Request; 7use Illuminate\View\View; 8 9class PostController extends Controller10{11 /**12 * Show the form to create a new blog post.13 */14 public function create(): View15 {16 return view('post.create');17 }18 19 /**20 * Store a new blog post.21 */22 public function store(Request $request): RedirectResponse23 {24 // Validate and store the blog post...25 26 $post = /** ... */27 28 return to_route('post.show', ['post' => $post->id]);29 }30}
バリデーションロジックの記述
これで、新しいブログ投稿をバリデーションするロジックをstoreメソッドに記述する準備ができました。これを行うには、Illuminate\Http\Requestオブジェクトによって提供されるvalidateメソッドを使用します。バリデーションルールに合格すると、コードは正常に実行され続けます。しかし、バリデーションに失敗すると、Illuminate\Validation\ValidationException例外が投げられ、適切なエラーレスポンスが自動的にユーザーに返されます。
従来のHTTPリクエスト中にバリデーションが失敗した場合、直前のURLへのリダイレクトレスポンスが生成されます。受信リクエストがXHRリクエストの場合、バリデーションエラーメッセージを含むJSONレスポンスが返されます。
validateメソッドをよりよく理解するために、storeメソッドに戻りましょう。
1/** 2 * Store a new blog post. 3 */ 4public function store(Request $request): RedirectResponse 5{ 6 $validated = $request->validate([ 7 'title' => 'required|unique:posts|max:255', 8 'body' => 'required', 9 ]);10 11 // The blog post is valid...12 13 return redirect('/posts');14}
ご覧のとおり、バリデーションルールはvalidateメソッドに渡されます。心配ありません。利用可能なすべてのバリデーションルールはドキュメント化されています。繰り返しますが、バリデーションが失敗した場合、適切なレスポンスが自動的に生成されます。バリデーションが合格した場合、コントローラは正常に実行を続けます。
あるいは、バリデーションルールは、単一の|区切り文字列の代わりに、ルールの配列として指定することもできます。
1$validatedData = $request->validate([2 'title' => ['required', 'unique:posts', 'max:255'],3 'body' => ['required'],4]);
さらに、validateWithBagメソッドを使用してリクエストをバリデーションし、エラーメッセージを名前付きエラーバッグ内に保存することもできます。
1$validatedData = $request->validateWithBag('post', [2 'title' => ['required', 'unique:posts', 'max:255'],3 'body' => ['required'],4]);
最初のバリデーション失敗時に停止
属性に対するバリデーションルールの実行を、最初のバリデーション失敗後に停止したい場合があります。そのためには、属性にbailルールを割り当てます。
1$request->validate([2 'title' => 'bail|required|unique:posts|max:255',3 'body' => 'required',4]);
この例では、title属性のuniqueルールが失敗した場合、maxルールはチェックされません。ルールは割り当てられた順にバリデーションされます。
ネストした属性に関する注意
受信HTTPリクエストに「ネストした」フィールドデータが含まれている場合、バリデーションルールでこれらのフィールドを「ドット」記法を使用して指定できます。
1$request->validate([2 'title' => 'required|unique:posts|max:255',3 'author.name' => 'required',4 'author.description' => 'required',5]);
一方、フィールド名にリテラルのピリオドが含まれている場合は、バックスラッシュでピリオドをエスケープすることで、「ドット」記法として解釈されるのを明示的に防ぐことができます。
1$request->validate([2 'title' => 'required|unique:posts|max:255',3 'v1\.0' => 'required',4]);
バリデーションエラーの表示
では、受信リクエストのフィールドが指定されたバリデーションルールに合格しなかった場合はどうなるでしょうか?前述したように、Laravelは自動的にユーザーを直前の場所にリダイレクトします。さらに、すべてのバリデーションエラーとリクエスト入力は、自動的にセッションへ一時保存されます。
$errors変数は、webミドルウェアグループによって提供されるIlluminate\View\Middleware\ShareErrorsFromSessionミドルウェアによって、アプリケーションのすべてのビューで共有されます。このミドルウェアが適用されると、$errors変数はビューで常に利用可能になり、$errors変数が常に定義されていて安全に使用できると便利に仮定できます。$errors変数はIlluminate\Support\MessageBagのインスタンスになります。このオブジェクトの操作に関する詳細については、そのドキュメントを確認してください。
したがって、この例では、バリデーションが失敗すると、ユーザーはコントローラのcreateメソッドにリダイレクトされ、ビューでエラーメッセージを表示できるようになります。
1<!-- /resources/views/post/create.blade.php --> 2 3<h1>Create Post</h1> 4 5@if ($errors->any()) 6 <div class="alert alert-danger"> 7 <ul> 8 @foreach ($errors->all() as $error) 9 <li>{{ $error }}</li>10 @endforeach11 </ul>12 </div>13@endif14 15<!-- Create Post Form -->
エラーメッセージのカスタマイズ
Laravelの組み込みバリデーションルールにはそれぞれ、アプリケーションのlang/en/validation.phpファイルにあるエラーメッセージがあります。アプリケーションにlangディレクトリがない場合は、lang:publish Artisanコマンドを使用してLaravelに作成を指示できます。
lang/en/validation.phpファイル内には、各バリデーションルールの翻訳エントリがあります。アプリケーションのニーズに応じて、これらのメッセージを自由に変更または修正できます。
さらに、このファイルを別の言語ディレクトリにコピーして、アプリケーションの言語のメッセージを翻訳することもできます。Laravelのローカリゼーションについて詳しく知るには、完全なローカリゼーションのドキュメントを確認してください。
デフォルトでは、Laravelアプリケーションスケルトンにはlangディレクトリは含まれていません。Laravelの言語ファイルをカスタマイズしたい場合は、lang:publish Artisanコマンドを介して公開できます。
XHRリクエストとバリデーション
この例では、従来のフォームを使用してアプリケーションにデータを送信しました。しかし、多くのアプリケーションはJavaScript駆動のフロントエンドからXHRリクエストを受け取ります。XHRリクエスト中にvalidateメソッドを使用する場合、Laravelはリダイレクトレスポンスを生成しません。代わりに、Laravelはすべてのバリデーションエラーを含むJSONレスポンスを生成します。このJSONレスポンスは、422 HTTPステータスコードで送信されます。
@errorディレクティブ
@error Bladeディレクティブを使用して、特定の属性にバリデーションエラーメッセージが存在するかどうかをすばやく判断できます。@errorディレクティブ内で、$message変数を出力してエラーメッセージを表示できます。
1<!-- /resources/views/post/create.blade.php --> 2 3<label for="title">Post Title</label> 4 5<input 6 id="title" 7 type="text" 8 name="title" 9 class="@error('title') is-invalid @enderror"10/>11 12@error('title')13 <div class="alert alert-danger">{{ $message }}</div>14@enderror
名前付きエラーバッグを使用している場合は、エラーバッグの名前を@errorディレクティブの2番目の引数として渡すことができます。
1<input ... class="@error('title', 'post') is-invalid @enderror">
フォームの再表示
Laravelがバリデーションエラーのためにリダイレクトレスポンスを生成すると、フレームワークは自動的にリクエストのすべての入力をセッションに一時保存します。これは、次のリクエストで入力に便利にアクセスし、ユーザーが送信しようとしたフォームを再表示できるようにするためです。
前のリクエストから一時保存された入力を取得するには、Illuminate\Http\Requestのインスタンスでoldメソッドを呼び出します。oldメソッドは、セッションから以前に一時保存された入力データを取得します。
1$title = $request->old('title');
Laravelはグローバルなoldヘルパも提供しています。Bladeテンプレート内で古い入力を表示している場合は、oldヘルパを使用してフォームを再表示する方が便利です。指定されたフィールドに古い入力が存在しない場合は、nullが返されます。
1<input type="text" name="title" value="{{ old('title') }}">
オプションフィールドに関する注意
デフォルトでは、LaravelはアプリケーションのグローバルミドルウェアスタックにTrimStringsおよびConvertEmptyStringsToNullミドルウェアを含んでいます。このため、バリデータにnull値を無効と見なさせたくない場合は、「オプションの」リクエストフィールドをnullableとしてマークする必要がよくあります。例:
1$request->validate([2 'title' => 'required|unique:posts|max:255',3 'body' => 'required',4 'publish_at' => 'nullable|date',5]);
この例では、publish_atフィールドがnullまたは有効な日付表現のいずれかであることを指定しています。nullable修飾子がルール定義に追加されていない場合、バリデータはnullを無効な日付と見なします。
バリデーションエラーレスポンス形式
アプリケーションがIlluminate\Validation\ValidationException例外を投げ、受信HTTPリクエストがJSONレスポンスを期待している場合、Laravelはエラーメッセージを自動的にフォーマットし、422 Unprocessable Entity HTTPレスポンスを返します。
以下に、バリデーションエラーのJSONレスポンス形式の例を確認できます。ネストしたエラーキーは「ドット」記法形式にフラット化されることに注意してください。
1{ 2 "message": "The team name must be a string. (and 4 more errors)", 3 "errors": { 4 "team_name": [ 5 "The team name must be a string.", 6 "The team name must be at least 1 characters." 7 ], 8 "authorization.role": [ 9 "The selected authorization.role is invalid."10 ],11 "users.0.email": [12 "The users.0.email field is required."13 ],14 "users.2.email": [15 "The users.2.email must be a valid email address."16 ]17 }18}
フォームリクエストバリデーション
フォームリクエストの作成
より複雑なバリデーションシナリオでは、「フォームリクエスト」を作成したい場合があります。フォームリクエストは、独自のバリデーションと認可ロジックをカプセル化するカスタムリクエストクラスです。フォームリクエストクラスを作成するには、make:request Artisan CLIコマンドを使用できます。
1php artisan make:request StorePostRequest
生成されたフォームリクエストクラスは、app/Http/Requestsディレクトリに配置されます。このディレクトリが存在しない場合、make:requestコマンドを実行すると作成されます。Laravelによって生成された各フォームリクエストには、authorizeとrulesの2つのメソッドがあります。
ご想像のとおり、authorizeメソッドは現在認証されているユーザーがリクエストによって表されるアクションを実行できるかどうかを判断する責任があり、rulesメソッドはリクエストのデータに適用されるべきバリデーションルールを返します。
1/** 2 * Get the validation rules that apply to the request. 3 * 4 * @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string> 5 */ 6public function rules(): array 7{ 8 return [ 9 'title' => 'required|unique:posts|max:255',10 'body' => 'required',11 ];12}
rulesメソッドのシグネチャ内で必要な依存関係をタイプヒントすることができます。それらはLaravelのサービスコンテナを介して自動的に解決されます。
では、バリデーションルールはどのように評価されるのでしょうか?コントローラメソッドでリクエストをタイプヒントするだけです。受信フォームリクエストはコントローラメソッドが呼び出される前にバリデーションされるため、コントローラをバリデーションロジックで乱雑にする必要はありません。
1/** 2 * Store a new blog post. 3 */ 4public function store(StorePostRequest $request): RedirectResponse 5{ 6 // The incoming request is valid... 7 8 // Retrieve the validated input data... 9 $validated = $request->validated();10 11 // Retrieve a portion of the validated input data...12 $validated = $request->safe()->only(['name', 'email']);13 $validated = $request->safe()->except(['name', 'email']);14 15 // Store the blog post...16 17 return redirect('/posts');18}
バリデーションが失敗した場合、ユーザーを直前の場所に戻すためのリダイレクトレスポンスが生成されます。エラーはセッションにも一時保存されるため、表示できます。リクエストがXHRリクエストだった場合、422ステータスコードのHTTPレスポンスが、バリデーションエラーのJSON表現を含んでユーザーに返されます。
Inertia駆動のLaravelフロントエンドにリアルタイムのフォームリクエストバリデーションを追加する必要がありますか?Laravel Precognitionをチェックしてください。
追加のバリデーションの実行
初期バリデーションが完了した後に追加のバリデーションを実行する必要がある場合があります。これは、フォームリクエストのafterメソッドを使用して実現できます。
afterメソッドは、バリデーション完了後に呼び出される呼び出し可能要素またはクロージャの配列を返す必要があります。指定された呼び出し可能要素はIlluminate\Validation\Validatorインスタンスを受け取るため、必要に応じて追加のエラーメッセージを発生させることができます。
1use Illuminate\Validation\Validator; 2 3/** 4 * Get the "after" validation callables for the request. 5 */ 6public function after(): array 7{ 8 return [ 9 function (Validator $validator) {10 if ($this->somethingElseIsInvalid()) {11 $validator->errors()->add(12 'field',13 'Something is wrong with this field!'14 );15 }16 }17 ];18}
前述のとおり、afterメソッドが返す配列には、呼び出し可能なクラスを含めることもできます。これらのクラスの__invokeメソッドは、Illuminate\Validation\Validatorインスタンスを受け取ります。
1use App\Validation\ValidateShippingTime; 2use App\Validation\ValidateUserStatus; 3use Illuminate\Validation\Validator; 4 5/** 6 * Get the "after" validation callables for the request. 7 */ 8public function after(): array 9{10 return [11 new ValidateUserStatus,12 new ValidateShippingTime,13 function (Validator $validator) {14 //15 }16 ];17}
最初のバリデーション失敗時に停止
リクエストクラスにstopOnFirstFailureプロパティを追加することで、バリデーションが1つの失敗が発生した時点で、すべての属性のバリデーションを停止するようバリデータに指示できます。
1/**2 * Indicates if the validator should stop on the first rule failure.3 *4 * @var bool5 */6protected $stopOnFirstFailure = true;
リダイレクト先のカスタマイズ
フォームリクエストのバリデーションが失敗すると、ユーザーを前の場所に戻すリダイレクトレスポンスが生成されます。ただし、この動作は自由にカスタマイズできます。そのためには、フォームリクエストに$redirectプロパティを定義します。
1/**2 * The URI that users should be redirected to if validation fails.3 *4 * @var string5 */6protected $redirect = '/dashboard';
または、名前付きルートにユーザーをリダイレクトしたい場合は、代わりに$redirectRouteプロパティを定義できます。
1/**2 * The route that users should be redirected to if validation fails.3 *4 * @var string5 */6protected $redirectRoute = 'dashboard';
フォームリクエストの認可
フォームリクエストクラスにはauthorizeメソッドも含まれています。このメソッド内で、認証済みユーザーが特定のりソースを更新する権限を実際に持っているかどうかを判断できます。たとえば、ユーザーが更新しようとしているブログコメントを実際に所有しているかどうかを判断できます。おそらく、このメソッド内で認可ゲートとポリシーを操作することになるでしょう。
1use App\Models\Comment; 2 3/** 4 * Determine if the user is authorized to make this request. 5 */ 6public function authorize(): bool 7{ 8 $comment = Comment::find($this->route('comment')); 9 10 return $comment && $this->user()->can('update', $comment);11}
すべてのフォームリクエストは基本のLaravelリクエストクラスを拡張しているため、userメソッドを使用して現在認証されているユーザーにアクセスできます。また、上記の例でのrouteメソッドの呼び出しに注意してください。このメソッドは、以下の例の{comment}パラメータなど、呼び出されているルートで定義されているURIパラメータへのアクセスを許可します。
1Route::post('/comment/{comment}');
したがって、アプリケーションがルートモデルバインディングを利用している場合、解決されたモデルをリクエストのプロパティとしてアクセスすることで、コードをさらに簡潔にすることができます。
1return $this->user()->can('update', $this->comment);
authorizeメソッドがfalseを返した場合、403ステータスコードのHTTPレスポンスが自動的に返され、コントローラメソッドは実行されません。
アプリケーションの別の部分でリクエストの認可ロジックを処理する予定の場合は、authorizeメソッドを完全に削除するか、単にtrueを返すことができます。
1/**2 * Determine if the user is authorized to make this request.3 */4public function authorize(): bool5{6 return true;7}
authorizeメソッドのシグネチャ内で必要な依存関係をタイプヒントできます。それらはLaravelのサービスコンテナを介して自動的に解決されます。
エラーメッセージのカスタマイズ
フォームリクエストで使用されるエラーメッセージは、messagesメソッドをオーバーライドすることでカスタマイズできます。このメソッドは、属性とルールのペアと、それに対応するエラーメッセージの配列を返す必要があります。
1/** 2 * Get the error messages for the defined validation rules. 3 * 4 * @return array<string, string> 5 */ 6public function messages(): array 7{ 8 return [ 9 'title.required' => 'A title is required',10 'body.required' => 'A message is required',11 ];12}
バリデーション属性のカスタマイズ
Laravelの組み込みバリデーションルールのエラーメッセージの多くには、:attributeプレースホルダが含まれています。バリデーションメッセージの:attributeプレースホルダをカスタム属性名に置き換えたい場合は、attributesメソッドをオーバーライドしてカスタム名を指定できます。このメソッドは、属性と名前のペアの配列を返す必要があります。
1/** 2 * Get custom attributes for validator errors. 3 * 4 * @return array<string, string> 5 */ 6public function attributes(): array 7{ 8 return [ 9 'email' => 'email address',10 ];11}
バリデーションのための入力準備
バリデーションルールを適用する前にリクエストからデータを準備またはサニタイズする必要がある場合は、prepareForValidationメソッドを使用できます。
1use Illuminate\Support\Str; 2 3/** 4 * Prepare the data for validation. 5 */ 6protected function prepareForValidation(): void 7{ 8 $this->merge([ 9 'slug' => Str::slug($this->slug),10 ]);11}
同様に、バリデーション完了後にリクエストデータを正規化する必要がある場合は、passedValidationメソッドを使用できます。
1/**2 * Handle a passed validation attempt.3 */4protected function passedValidation(): void5{6 $this->replace(['name' => 'Taylor']);7}
バリデータの手動作成
リクエストのvalidateメソッドを使用したくない場合は、Validator ファサードを使用してバリデータインスタンスを手動で作成できます。ファサードのmakeメソッドは、新しいバリデータインスタンスを生成します。
1<?php 2 3namespace App\Http\Controllers; 4 5use Illuminate\Http\RedirectResponse; 6use Illuminate\Http\Request; 7use Illuminate\Support\Facades\Validator; 8 9class PostController extends Controller10{11 /**12 * Store a new blog post.13 */14 public function store(Request $request): RedirectResponse15 {16 $validator = Validator::make($request->all(), [17 'title' => 'required|unique:posts|max:255',18 'body' => 'required',19 ]);20 21 if ($validator->fails()) {22 return redirect('/post/create')23 ->withErrors($validator)24 ->withInput();25 }26 27 // Retrieve the validated input...28 $validated = $validator->validated();29 30 // Retrieve a portion of the validated input...31 $validated = $validator->safe()->only(['name', 'email']);32 $validated = $validator->safe()->except(['name', 'email']);33 34 // Store the blog post...35 36 return redirect('/posts');37 }38}
makeメソッドに渡される最初の引数は、バリデーション対象のデータです。2番目の引数は、データに適用されるべきバリデーションルールの配列です。
リクエストのバリデーションが失敗したかどうかを判断した後、withErrorsメソッドを使用してエラーメッセージをセッションに一時保存できます。このメソッドを使用すると、$errors変数はリダイレクト後にビューと自動的に共有され、ユーザーに簡単に表示できるようになります。withErrorsメソッドは、バリデータ、MessageBag、またはPHPのarrayを受け入れます。
最初のバリデーション失敗時に停止
stopOnFirstFailureメソッドは、1つのバリデーション失敗が発生した時点で、すべての属性のバリデーションを停止するようバリデータに通知します。
1if ($validator->stopOnFirstFailure()->fails()) {2 // ...3}
自動リダイレクト
バリデータインスタンスを手動で作成しつつも、HTTPリクエストのvalidateメソッドが提供する自動リダイレクトを利用したい場合は、既存のバリデータインスタンスでvalidateメソッドを呼び出すことができます。バリデーションが失敗した場合、ユーザーは自動的にリダイレクトされるか、XHRリクエストの場合はJSONレスポンスが返されます。
1Validator::make($request->all(), [2 'title' => 'required|unique:posts|max:255',3 'body' => 'required',4])->validate();
バリデーションが失敗した場合、validateWithBagメソッドを使用して、エラーメッセージを名前付きエラーバッグに保存できます。
1Validator::make($request->all(), [2 'title' => 'required|unique:posts|max:255',3 'body' => 'required',4])->validateWithBag('post');
名前付きエラーバッグ
1つのページに複数のフォームがある場合、バリデーションエラーを含むMessageBagに名前を付けて、特定のフォームのエラーメッセージを取得したい場合があります。これを実現するには、withErrorsの2番目の引数として名前を渡します。
1return redirect('/register')->withErrors($validator, 'login');
その後、$errors変数から名前付きのMessageBagインスタンスにアクセスできます。
1{{ $errors->login->first('email') }}
エラーメッセージのカスタマイズ
必要であれば、Laravelが提供するデフォルトのエラーメッセージの代わりに、バリデータインスタンスが使用するカスタムエラーメッセージを提供できます。カスタムメッセージを指定するには、いくつかの方法があります。まず、Validator::makeメソッドの3番目の引数としてカスタムメッセージを渡すことができます。
1$validator = Validator::make($input, $rules, $messages = [2 'required' => 'The :attribute field is required.',3]);
この例では、:attributeプレースホルダーは、バリデーション対象のフィールドの実際の名前で置き換えられます。バリデーションメッセージでは、他のプレースホルダーも利用できます。例:
1$messages = [2 'same' => 'The :attribute and :other must match.',3 'size' => 'The :attribute must be exactly :size.',4 'between' => 'The :attribute value :input is not between :min - :max.',5 'in' => 'The :attribute must be one of the following types: :values',6];
特定の属性に対するカスタムメッセージの指定
特定の属性に対してのみカスタムエラーメッセージを指定したい場合があります。これは「ドット」記法を使用して行うことができます。最初に属性の名前を指定し、次にルールを指定します。
1$messages = [2 'email.required' => 'We need to know your email address!',3];
カスタム属性値の指定
Laravelの組み込みエラーメッセージの多くには、バリデーション対象のフィールドまたは属性の名前で置き換えられる:attributeプレースホルダーが含まれています。特定のフィールドに対してこれらのプレースホルダーを置き換えるために使用される値をカスタマイズするには、Validator::makeメソッドの4番目の引数としてカスタム属性の配列を渡すことができます。
1$validator = Validator::make($input, $rules, $messages, [2 'email' => 'email address',3]);
追加のバリデーションの実行
初期バリデーションが完了した後に追加のバリデーションを行う必要がある場合があります。これは、バリデータのafterメソッドを使用して達成できます。afterメソッドは、バリデーション完了後に呼び出されるクロージャまたは呼び出し可能要素の配列を受け入れます。与えられた呼び出し可能要素はIlluminate\Validation\Validatorインスタンスを受け取るため、必要に応じて追加のエラーメッセージを発生させることができます。
1use Illuminate\Support\Facades\Validator; 2 3$validator = Validator::make(/* ... */); 4 5$validator->after(function ($validator) { 6 if ($this->somethingElseIsInvalid()) { 7 $validator->errors()->add( 8 'field', 'Something is wrong with this field!' 9 );10 }11});12 13if ($validator->fails()) {14 // ...15}
前述のとおり、afterメソッドは呼び出し可能要素の配列も受け入れます。これは、「バリデーション後」のロジックが呼び出し可能なクラスにカプセル化されている場合に特に便利で、それらの__invokeメソッドを介してIlluminate\Validation\Validatorインスタンスを受け取ります。
1use App\Validation\ValidateShippingTime; 2use App\Validation\ValidateUserStatus; 3 4$validator->after([ 5 new ValidateUserStatus, 6 new ValidateShippingTime, 7 function ($validator) { 8 // ... 9 },10]);
バリデーション済み入力の操作
フォームリクエストまたは手動で作成したバリデータインスタンスを使用して受信リクエストデータをバリデーションした後、実際にバリデーションされた受信リクエストデータを取得したい場合があります。これはいくつかの方法で実現できます。まず、フォームリクエストまたはバリデータインスタンスでvalidatedメソッドを呼び出すことができます。このメソッドは、バリデーションされたデータの配列を返します。
1$validated = $request->validated();2 3$validated = $validator->validated();
あるいは、フォームリクエストまたはバリデータインスタンスでsafeメソッドを呼び出すこともできます。このメソッドはIlluminate\Support\ValidatedInputのインスタンスを返します。このオブジェクトは、バリデーションされたデータのサブセットまたはバリデーションされたデータの配列全体を取得するためのonly、except、およびallメソッドを公開しています。
1$validated = $request->safe()->only(['name', 'email']);2 3$validated = $request->safe()->except(['name', 'email']);4 5$validated = $request->safe()->all();
さらに、Illuminate\Support\ValidatedInputインスタンスは、繰り返し処理したり、配列のようにアクセスしたりすることができます。
1// Validated data may be iterated...2foreach ($request->safe() as $key => $value) {3 // ...4}5 6// Validated data may be accessed as an array...7$validated = $request->safe();8 9$email = $validated['email'];
バリデーション済みのデータに追加のフィールドを加えたい場合は、mergeメソッドを呼び出すことができます。
1$validated = $request->safe()->merge(['name' => 'Taylor Otwell']);
バリデーション済みデータをコレクションインスタンスとして取得したい場合は、collectメソッドを呼び出すことができます。
1$collection = $request->safe()->collect();
エラーメッセージの操作
Validatorインスタンスでerrorsメソッドを呼び出すと、Illuminate\Support\MessageBagインスタンスが返されます。これには、エラーメッセージを操作するためのさまざまな便利なメソッドがあります。すべてのビューで自動的に利用可能になる$errors変数も、MessageBagクラスのインスタンスです。
フィールドの最初のエラーメッセージの取得
指定されたフィールドの最初のエラーメッセージを取得するには、firstメソッドを使用します。
1$errors = $validator->errors();2 3echo $errors->first('email');
フィールドのすべてのエラーメッセージの取得
指定されたフィールドのすべてのメッセージの配列を取得する必要がある場合は、getメソッドを使用します。
1foreach ($errors->get('email') as $message) {2 // ...3}
配列フォームフィールドをバリデーションしている場合、*文字を使用して各配列要素のすべてのメッセージを取得できます。
1foreach ($errors->get('attachments.*') as $message) {2 // ...3}
すべてのフィールドのすべてのエラーメッセージの取得
すべてのフィールドのすべてのメッセージの配列を取得するには、allメソッドを使用します。
1foreach ($errors->all() as $message) {2 // ...3}
フィールドにメッセージが存在するかどうかの判断
hasメソッドを使用して、特定のフィールドにエラーメッセージが存在するかどうかを判断できます。
1if ($errors->has('email')) {2 // ...3}
言語ファイルでのカスタムメッセージの指定
Laravelの組み込みバリデーションルールにはそれぞれ、アプリケーションのlang/en/validation.phpファイルにあるエラーメッセージがあります。アプリケーションにlangディレクトリがない場合は、lang:publish Artisanコマンドを使用してLaravelに作成を指示できます。
lang/en/validation.phpファイル内には、各バリデーションルールの翻訳エントリがあります。アプリケーションのニーズに応じて、これらのメッセージを自由に変更または修正できます。
さらに、このファイルを別の言語ディレクトリにコピーして、アプリケーションの言語のメッセージを翻訳することもできます。Laravelのローカリゼーションについて詳しく知るには、完全なローカリゼーションのドキュメントを確認してください。
デフォルトでは、Laravelアプリケーションスケルトンにはlangディレクトリは含まれていません。Laravelの言語ファイルをカスタマイズしたい場合は、lang:publish Artisanコマンドを介して公開できます。
特定属性のカスタムメッセージ
アプリケーションのバリデーション言語ファイル内で、指定した属性とルールの組み合わせに使用するエラーメッセージをカスタマイズできます。そのためには、アプリケーションのlang/xx/validation.php言語ファイルのcustom配列にメッセージのカスタマイズを追加します。
1'custom' => [2 'email' => [3 'required' => 'We need to know your email address!',4 'max' => 'Your email address is too long!'5 ],6],
言語ファイルでの属性の指定
Laravelの組み込みエラーメッセージの多くには、バリデーション対象のフィールドまたは属性の名前で置き換えられる:attributeプレースホルダーが含まれています。バリデーションメッセージの:attribute部分をカスタム値に置き換えたい場合は、lang/xx/validation.php言語ファイルのattributes配列でカスタム属性名を指定できます。
1'attributes' => [2 'email' => 'email address',3],
デフォルトでは、Laravelアプリケーションスケルトンにはlangディレクトリは含まれていません。Laravelの言語ファイルをカスタマイズしたい場合は、lang:publish Artisanコマンドを介して公開できます。
言語ファイルでの値の指定
Laravelの組み込みバリデーションルールエラーメッセージの一部には、リクエスト属性の現在の値に置き換えられる:valueプレースホルダーが含まれています。しかし、バリデーションメッセージの:value部分を値のカスタム表現に置き換える必要がある場合があります。たとえば、payment_typeの値がccの場合にクレジットカード番号が必要であることを指定する次のルールを考えてみましょう。
1Validator::make($request->all(), [2 'credit_card_number' => 'required_if:payment_type,cc'3]);
このバリデーションルールが失敗すると、次のエラーメッセージが生成されます。
1The credit card number field is required when payment type is cc.
支払いタイプの値としてccを表示する代わりに、lang/xx/validation.php言語ファイルでvalues配列を定義することにより、よりユーザーフレンドリーな値の表現を指定できます。
1'values' => [2 'payment_type' => [3 'cc' => 'credit card'4 ],5],
デフォルトでは、Laravelアプリケーションスケルトンにはlangディレクトリは含まれていません。Laravelの言語ファイルをカスタマイズしたい場合は、lang:publish Artisanコマンドを介して公開できます。
この値を定義した後、バリデーションルールは次のエラーメッセージを生成します。
1The credit card number field is required when payment type is credit card.
利用可能なバリデーションルール
以下は、利用可能なすべてのバリデーションルールとその機能のリストです。
真偽値
文字列
Active URL Alpha Alpha Dash Alpha Numeric Ascii Confirmed Current Password Different Doesnt Start With Doesnt End With Email Ends With Enum Hex Color In IP Address JSON Lowercase MAC Address Max Min Not In Regular Expression Not Regular Expression Same Size Starts With String Uppercase URL ULID UUID
数値
Between Decimal Different Digits Digits Between Greater Than Greater Than Or Equal Integer Less Than Less Than Or Equal Max Max Digits Min Min Digits Multiple Of Numeric Same Size
配列
日付
ファイル
データベース
ユーティリティ
Bail Exclude Exclude If Exclude Unless Exclude With Exclude Without Filled Missing Missing If Missing Unless Missing With Missing With All Nullable Present Present If Present Unless Present With Present With All Prohibited Prohibited If Prohibited Unless Prohibits Required Required If Required If Accepted Required If Declined Required Unless Required With Required With All Required Without Required Without All Required Array Keys Sometimes
accepted
バリデーション対象のフィールドは、"yes"、"on"、1、"1"、true、または"true"でなければなりません。これは、「利用規約」の同意などのフィールドのバリデーションに役立ちます。
accepted_if:anotherfield,value,...
バリデーション対象のフィールドは、別のバリデーション対象のフィールドが指定された値と等しい場合に、"yes"、"on"、1、"1"、true、または"true"でなければなりません。これは、「利用規約」の同意などのフィールドのバリデーションに役立ちます。
active_url
バリデーション対象のフィールドは、PHPのdns_get_record関数によると、有効なAレコードまたはAAAAレコードを持っている必要があります。提供されたURLのホスト名は、dns_get_recordに渡される前にparse_url PHP関数を使用して抽出されます。
after:date
バリデーション対象のフィールドは、指定された日付より後の値でなければなりません。日付は、有効なDateTimeインスタンスに変換するために、PHPのstrtotime関数に渡されます。
1'start_date' => 'required|date|after:tomorrow'
strtotimeによって評価される日付文字列を渡す代わりに、日付と比較する別のフィールドを指定することもできます。
1'finish_date' => 'required|date|after:start_date'
便宜上、日付ベースのルールは、流暢なdateルールビルダーを使用して構築できます。
1use Illuminate\Validation\Rule;2 3'start_date' => [4 'required',5 Rule::date()->after(today()->addDays(7)),6],
afterTodayおよびtodayOrAfterメソッドを使用して、日付が今日より後または今日以降であることを流暢に表現できます。
1'start_date' => [2 'required',3 Rule::date()->afterToday(),4],
after_or_equal:date
バリデーション対象のフィールドは、指定された日付以降の値でなければなりません。詳細については、afterルールを参照してください。
便宜上、日付ベースのルールは、流暢なdateルールビルダーを使用して構築できます。
1use Illuminate\Validation\Rule;2 3'start_date' => [4 'required',5 Rule::date()->afterOrEqual(today()->addDays(7)),6],
alpha
バリデーション対象のフィールドは、\p{L}および\p{M}に含まれるUnicodeアルファベット文字のみでなければなりません。
このバリデーションルールをASCII範囲(a-zおよびA-Z)の文字に制限するには、バリデーションルールにasciiオプションを提供できます。
1'username' => 'alpha:ascii',
alpha_dash
バリデーション対象のフィールドは、\p{L}、\p{M}、\p{N}に含まれるUnicode英数字、およびASCIIダッシュ(-)とASCIIアンダースコア(_)のみでなければなりません。
このバリデーションルールをASCII範囲(a-zおよびA-Z)の文字に制限するには、バリデーションルールにasciiオプションを提供できます。
1'username' => 'alpha_dash:ascii',
alpha_num
バリデーション対象のフィールドは、\p{L}、\p{M}、および\p{N}に含まれるUnicode英数字のみでなければなりません。
このバリデーションルールをASCII範囲(a-zおよびA-Z)の文字に制限するには、バリデーションルールにasciiオプションを提供できます。
1'username' => 'alpha_num:ascii',
array
バリデーション対象のフィールドはPHPのarrayでなければなりません。
arrayルールに追加の値が提供された場合、入力配列の各キーはルールに提供された値のリスト内に存在しなければなりません。次の例では、入力配列のadminキーは、arrayルールに提供された値のリストに含まれていないため無効です。
1use Illuminate\Support\Facades\Validator; 2 3$input = [ 4 'user' => [ 5 'name' => 'Taylor Otwell', 6 'username' => 'taylorotwell', 7 'admin' => true, 8 ], 9];10 11Validator::make($input, [12 'user' => 'array:name,username',13]);
一般的に、配列内に存在することが許可されている配列キーは常に指定すべきです。
ascii
バリデーション対象のフィールドは、完全に7ビットASCII文字でなければなりません。
bail
最初のバリデーション失敗後、フィールドのバリデーションルールの実行を停止します。
bailルールはバリデーション失敗に遭遇した際に特定のフィールドのバリデーションのみを停止しますが、stopOnFirstFailureメソッドは、単一のバリデーション失敗が発生した時点で、すべての属性のバリデーションを停止するようバリデータに指示します。
1if ($validator->stopOnFirstFailure()->fails()) {2 // ...3}
before:date
バリデーション対象のフィールドは、指定された日付より前の値でなければなりません。日付は、有効なDateTimeインスタンスに変換するためにPHPのstrtotime関数に渡されます。さらに、afterルールと同様に、バリデーション対象の別のフィールドの名前をdateの値として指定できます。
便宜上、日付ベースのルールは、流暢なdateルールビルダーを使用して構築することもできます。
1use Illuminate\Validation\Rule;2 3'start_date' => [4 'required',5 Rule::date()->before(today()->subDays(7)),6],
beforeTodayおよびtodayOrBeforeメソッドを使用して、日付が今日より前または今日以前であることを流暢に表現できます。
1'start_date' => [2 'required',3 Rule::date()->beforeToday(),4],
before_or_equal:date
バリデーション対象のフィールドは、指定された日付以前の値でなければなりません。日付は、有効なDateTimeインスタンスに変換するためにPHPのstrtotime関数に渡されます。さらに、afterルールと同様に、バリデーション対象の別のフィールドの名前をdateの値として指定できます。
便宜上、日付ベースのルールは、流暢なdateルールビルダーを使用して構築することもできます。
1use Illuminate\Validation\Rule;2 3'start_date' => [4 'required',5 Rule::date()->beforeOrEqual(today()->subDays(7)),6],
between:min,max
バリデーション対象のフィールドは、指定されたminとmaxの間のサイズでなければなりません(minとmaxを含みます)。文字列、数値、配列、およびファイルは、sizeルールと同じ方法で評価されます。
boolean
バリデーション対象のフィールドは、ブール値にキャストできる必要があります。受け入れられる入力は、true、false、1、0、"1"、および"0"です。
confirmed
バリデーション対象のフィールドには、{field}_confirmationという名前の一致するフィールドが必要です。たとえば、バリデーション対象のフィールドがpasswordの場合、入力に一致するpassword_confirmationフィールドが存在する必要があります。
カスタムの確認フィールド名を渡すこともできます。たとえば、confirmed:repeat_usernameは、フィールドrepeat_usernameがバリデーション対象のフィールドと一致することを期待します。
contains:foo,bar,...
バリデーション対象のフィールドは、指定されたすべてのパラメータ値を含む配列でなければなりません。
current_password
バリデーション対象のフィールドは、認証済みユーザーのパスワードと一致しなければなりません。ルールの最初のパラメータを使用して認証ガードを指定できます。
1'password' => 'current_password:api'
date
バリデーション対象のフィールドは、PHPのstrtotime関数によれば、有効で非相対的な日付でなければなりません。
date_equals:date
バリデーション対象のフィールドは、指定された日付と等しくなければなりません。日付は、有効なDateTimeインスタンスに変換するためにPHPのstrtotime関数に渡されます。
date_format:format,...
バリデーション対象のフィールドは、指定されたformatsのいずれかに一致する必要があります。フィールドをバリデーションする際は、dateまたはdate_formatのどちらか一方を使用し、両方を使用しないでください。このバリデーションルールは、PHPのDateTimeクラスがサポートするすべてのフォーマットをサポートしています。
便宜上、日付ベースのルールは、流暢なdateルールビルダーを使用して構築できます。
1use Illuminate\Validation\Rule;2 3'start_date' => [4 'required',5 Rule::date()->format('Y-m-d'),6],
decimal:min,max
バリデーション対象のフィールドは数値であり、指定された小数点以下の桁数を含んでいる必要があります。
1// Must have exactly two decimal places (9.99)...2'price' => 'decimal:2'3 4// Must have between 2 and 4 decimal places...5'price' => 'decimal:2,4'
declined
バリデーション対象のフィールドは、"no"、"off"、0、"0"、false、または"false"でなければなりません。
declined_if:anotherfield,value,...
バリデーション対象のフィールドは、別のバリデーション対象のフィールドが指定された値と等しい場合に、"no"、"off"、0、"0"、false、または"false"でなければなりません。
different:field
バリデーション対象のフィールドは、fieldとは異なる値でなければなりません。
digits:value
バリデーション対象の整数は、valueと完全に同じ長さでなければなりません。
digits_between:min,max
バリデーション対象の整数は、指定されたminとmaxの間の長さでなければなりません。
dimensions
バリデーション対象のファイルは、ルールのパラメータで指定された寸法の制約を満たす画像でなければなりません。
1'avatar' => 'dimensions:min_width=100,min_height=200'
利用可能な制約は次のとおりです:min_width、max_width、min_height、max_height、width、height、ratio。
ratio制約は、幅を高さで割ったものとして表されるべきです。これは、3/2のような分数または1.5のような浮動小数点数で指定できます。
1'avatar' => 'dimensions:ratio=3/2'
このルールはいくつかの引数を必要とするため、Rule::dimensionsメソッドを使用してルールを流暢に構築する方が便利な場合が多いです。
1use Illuminate\Support\Facades\Validator; 2use Illuminate\Validation\Rule; 3 4Validator::make($data, [ 5 'avatar' => [ 6 'required', 7 Rule::dimensions() 8 ->maxWidth(1000) 9 ->maxHeight(500)10 ->ratio(3 / 2),11 ],12]);
distinct
配列をバリデーションする場合、バリデーション対象のフィールドに重複した値があってはなりません。
1'foo.*.id' => 'distinct'
Distinctはデフォルトで緩い変数比較を使用します。厳密な比較を使用するには、バリデーションルール定義にstrictパラメータを追加できます。
1'foo.*.id' => 'distinct:strict'
バリデーションルールの引数にignore_caseを追加して、ルールが大文字と小文字の違いを無視するようにできます。
1'foo.*.id' => 'distinct:ignore_case'
doesnt_start_with:foo,bar,...
バリデーション対象のフィールドは、指定された値のいずれかで始まってはなりません。
doesnt_end_with:foo,bar,...
バリデーション対象のフィールドは、指定された値のいずれかで終わってはなりません。
バリデーション対象のフィールドは、電子メールアドレスとしてフォーマットされている必要があります。このバリデーションルールは、電子メールアドレスのバリデーションにegulias/email-validatorパッケージを利用します。デフォルトでは、RFCValidationバリデータが適用されますが、他のバリデーションスタイルを適用することもできます。
1'email' => 'email:rfc,dns'
上記の例では、RFCValidationとDNSCheckValidationのバリデーションが適用されます。適用できるバリデーションスタイルの完全なリストは次のとおりです。
rfc:RFCValidation- RFC 5322に従って電子メールアドレスをバリデーションします。strict:NoRFCWarningsValidation- RFC 5322に従って電子メールをバリデーションし、末尾のピリオドや連続する複数のピリオドを拒否します。dns:DNSCheckValidation- 電子メールアドレスのドメインに有効なMXレコードがあることを確認します。spoof:SpoofCheckValidation- 電子メールアドレスにホモグラフや紛らわしいUnicode文字が含まれていないことを確認します。filter:FilterEmailValidation- PHPのfilter_var関数に従って電子メールアドレスが有効であることを確認します。filter_unicode:FilterEmailValidation::unicode()- PHPのfilter_var関数に従って電子メールアドレスが有効であることを確認し、一部のUnicode文字を許可します。
便宜上、電子メールのバリデーションルールは、流暢なルールビルダーを使用して構築できます。
1use Illuminate\Validation\Rule; 2 3$request->validate([ 4 'email' => [ 5 'required', 6 Rule::email() 7 ->rfcCompliant(strict: false) 8 ->validateMxRecord() 9 ->preventSpoofing()10 ],11]);
dnsおよびspoofバリデータには、PHPのintl拡張機能が必要です。
ends_with:foo,bar,...
バリデーション対象のフィールドは、指定された値のいずれかで終わらなければなりません。
enum
Enumルールは、バリデーション対象のフィールドに有効な列挙型の値が含まれているかどうかを検証するクラスベースのルールです。Enumルールは、コンストラクタの唯一の引数として列挙型の名前を受け入れます。プリミティブ値を検証する場合、EnumルールにはBacked Enumを提供する必要があります。
1use App\Enums\ServerStatus;2use Illuminate\Validation\Rule;3 4$request->validate([5 'status' => [Rule::enum(ServerStatus::class)],6]);
Enumルールのonlyおよびexceptメソッドを使用して、有効と見なされる列挙型のケースを制限できます。
1Rule::enum(ServerStatus::class)2 ->only([ServerStatus::Pending, ServerStatus::Active]);3 4Rule::enum(ServerStatus::class)5 ->except([ServerStatus::Pending, ServerStatus::Active]);
whenメソッドを使用して、Enumルールを条件付きで変更できます。
1use Illuminate\Support\Facades\Auth;2use Illuminate\Validation\Rule;3 4Rule::enum(ServerStatus::class)5 ->when(6 Auth::user()->isAdmin(),7 fn ($rule) => $rule->only(...),8 fn ($rule) => $rule->only(...),9 );
exclude
バリデーション対象のフィールドは、validateおよびvalidatedメソッドによって返されるリクエストデータから除外されます。
exclude_if:anotherfield,value
anotherfieldフィールドがvalueと等しい場合、バリデーション対象のフィールドはvalidateおよびvalidatedメソッドによって返されるリクエストデータから除外されます。
複雑な条件付き除外ロジックが必要な場合は、Rule::excludeIfメソッドを利用できます。このメソッドは、ブール値またはクロージャを受け入れます。クロージャが与えられた場合、クロージャはバリデーション対象のフィールドを除外すべきかどうかを示すためにtrueまたはfalseを返す必要があります。
1use Illuminate\Support\Facades\Validator; 2use Illuminate\Validation\Rule; 3 4Validator::make($request->all(), [ 5 'role_id' => Rule::excludeIf($request->user()->is_admin), 6]); 7 8Validator::make($request->all(), [ 9 'role_id' => Rule::excludeIf(fn () => $request->user()->is_admin),10]);
exclude_unless:anotherfield,value
anotherfieldのフィールドがvalueと等しくない限り、バリデーション対象のフィールドはvalidateおよびvalidatedメソッドによって返されるリクエストデータから除外されます。valueがnullの場合(exclude_unless:name,null)、比較フィールドがnullであるか、比較フィールドがリクエストデータに存在しない限り、バリデーション対象のフィールドは除外されます。
exclude_with:anotherfield
anotherfieldフィールドが存在する場合、バリデーション対象のフィールドはvalidateおよびvalidatedメソッドによって返されるリクエストデータから除外されます。
exclude_without:anotherfield
anotherfieldフィールドが存在しない場合、バリデーション対象のフィールドはvalidateおよびvalidatedメソッドによって返されるリクエストデータから除外されます。
exists:table,column
バリデーション対象のフィールドは、指定されたデータベーステーブルに存在しなければなりません。
Existsルールの基本的な使用法
1'state' => 'exists:states'
columnオプションが指定されていない場合、フィールド名が使用されます。したがって、この場合、ルールはstatesデータベーステーブルに、リクエストのstate属性値と一致するstateカラム値を持つレコードが含まれていることを検証します。
カスタムカラム名の指定
バリデーションルールで使用されるべきデータベースカラム名を、データベーステーブル名の後に配置することで明示的に指定できます。
1'state' => 'exists:states,abbreviation'
時々、existsクエリに使用する特定のデータベース接続を指定する必要がある場合があります。これは、接続名をテーブル名の前に追加することで実現できます。
1'email' => 'exists:connection.staff,email'
テーブル名を直接指定する代わりに、テーブル名を決定するために使用するEloquentモデルを指定することもできます。
1'user_id' => 'exists:App\Models\User,id'
バリデーションルールによって実行されるクエリをカスタマイズしたい場合は、Ruleクラスを使用してルールを流暢に定義できます。この例では、バリデーションルールを|文字で区切る代わりに配列として指定します。
1use Illuminate\Database\Query\Builder; 2use Illuminate\Support\Facades\Validator; 3use Illuminate\Validation\Rule; 4 5Validator::make($data, [ 6 'email' => [ 7 'required', 8 Rule::exists('staff')->where(function (Builder $query) { 9 $query->where('account_id', 1);10 }),11 ],12]);
Rule::existsメソッドによって生成されるexistsルールで使用されるデータベースカラム名を、existsメソッドの2番目の引数としてカラム名を指定することで明示的に指定できます。
1'state' => Rule::exists('states', 'abbreviation'),
extensions:foo,bar,...
バリデーション対象のファイルは、リストされた拡張子のいずれかに対応するユーザーが割り当てた拡張子を持っている必要があります。
1'photo' => ['required', 'extensions:jpg,png'],
file
バリデーション対象のフィールドは、正常にアップロードされたファイルでなければなりません。
filled
バリデーション対象のフィールドは、存在している場合に空であってはなりません。
gt:field
バリデーション対象のフィールドは、指定されたfieldまたはvalueより大きくなければなりません。2つのフィールドは同じタイプでなければなりません。文字列、数値、配列、およびファイルは、sizeルールと同じ規則を使用して評価されます。
gte:field
バリデーション対象のフィールドは、指定されたfieldまたはvalue以上でなければなりません。2つのフィールドは同じタイプでなければなりません。文字列、数値、配列、およびファイルは、sizeルールと同じ規則を使用して評価されます。
hex_color
バリデーション対象のフィールドは、16進数形式の有効な色値を含んでいる必要があります。
image
バリデーション対象のファイルは、画像(jpg、jpeg、png、bmp、gif、またはwebp)でなければなりません。
デフォルトでは、XSS脆弱性の可能性があるため、imageルールはSVGファイルを許可しません。SVGファイルを許可する必要がある場合は、imageルールにallow_svgディレクティブを提供できます(image:allow_svg)。
in:foo,bar,...
バリデーション対象のフィールドは、指定された値のリストに含まれている必要があります。このルールはしばしば配列をimplodeする必要があるため、Rule::inメソッドを使用してルールを流暢に構築できます。
1use Illuminate\Support\Facades\Validator;2use Illuminate\Validation\Rule;3 4Validator::make($data, [5 'zones' => [6 'required',7 Rule::in(['first-zone', 'second-zone']),8 ],9]);
inルールがarrayルールと組み合わされると、入力配列の各値はinルールに提供された値のリスト内に存在しなければなりません。次の例では、入力配列のLAS空港コードは、inルールに提供された空港のリストに含まれていないため無効です。
1use Illuminate\Support\Facades\Validator; 2use Illuminate\Validation\Rule; 3 4$input = [ 5 'airports' => ['NYC', 'LAS'], 6]; 7 8Validator::make($input, [ 9 'airports' => [10 'required',11 'array',12 ],13 'airports.*' => Rule::in(['NYC', 'LIT']),14]);
in_array:anotherfield.*
バリデーション対象のフィールドは、anotherfieldの値の中に存在しなければなりません。
integer
バリデーション対象のフィールドは整数でなければなりません。
このバリデーションルールは、入力が「integer」変数タイプであることを検証するのではなく、入力が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タイプのいずれかに一致しなければなりません。
1'video' => 'mimetypes:video/avi,video/mpeg,video/quicktime'
アップロードされたファイルのMIMEタイプを決定するために、ファイルの内容が読み取られ、フレームワークはMIMEタイプを推測しようとします。これは、クライアントが提供したMIMEタイプとは異なる場合があります。
mimes:foo,bar,...
バリデーション対象のファイルは、リストされた拡張子のいずれかに対応するMIMEタイプを持っている必要があります。
1'photo' => 'mimes:jpg,bmp,png'
拡張子を指定するだけでよいですが、このルールは実際にはファイルの内容を読み取り、そのMIMEタイプを推測することによってファイルのMIMEタイプを検証します。MIMEタイプとその対応する拡張子の完全なリストは、次の場所で見つけることができます。
https://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types
MIMEタイプと拡張子
このバリデーションルールは、MIMEタイプとユーザーがファイルに割り当てた拡張子との間の一致を検証しません。たとえば、mimes:pngバリデーションルールは、ファイルが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メソッドを使用して、ルールを流暢に構築できます。
1use Illuminate\Validation\Rule;2 3Validator::make($data, [4 'toppings' => [5 'required',6 Rule::notIn(['sprinkles', 'cherries']),7 ],8]);
not_regex:pattern
バリデーション対象のフィールドは、指定された正規表現に一致してはなりません。
内部的に、このルールはPHPのpreg_match関数を使用します。指定するパターンは、preg_matchで要求されるのと同じ書式に従う必要があり、したがって有効なデリミタも含まれている必要があります。例:'email' => 'not_regex:/^.+$/i'。
regex / not_regexパターンを使用する場合、特に正規表現に|文字が含まれている場合は、|デリミタを使用する代わりに、バリデーションルールを配列で指定する必要がある場合があります。
nullable
バリデーション対象のフィールドはnullであってもかまいません。
numeric
バリデーション対象のフィールドは、数値でなければなりません。
present
バリデーション対象のフィールドは、入力データに存在しなければなりません。
present_if:anotherfield,value,...
anotherfieldフィールドがいずれかのvalueと等しい場合、バリデーション対象のフィールドは存在しなければなりません。
present_unless:anotherfield,value
anotherfieldフィールドがいずれかのvalueと等しくない限り、バリデーション対象のフィールドは存在しなければなりません。
present_with:foo,bar,...
バリデーション対象のフィールドは、他の指定されたフィールドのいずれかが存在する場合にのみ、存在しなければなりません。
present_with_all:foo,bar,...
バリデーション対象のフィールドは、他の指定されたフィールドがすべて存在する場合にのみ、存在しなければなりません。
prohibited
バリデーション対象のフィールドは、存在しないか空でなければなりません。フィールドが「空」であると見なされるのは、以下の基準のいずれかを満たす場合です。
- 値が
nullである。 - 値が空の文字列である。
- 値が空の配列または空の
Countableオブジェクトである。 - 値が空のパスを持つアップロードされたファイルである。
prohibited_if:anotherfield,value,...
anotherfieldフィールドがいずれかのvalueと等しい場合、バリデーション対象のフィールドは存在しないか空でなければなりません。フィールドが「空」であると見なされるのは、以下の基準のいずれかを満たす場合です。
- 値が
nullである。 - 値が空の文字列である。
- 値が空の配列または空の
Countableオブジェクトである。 - 値が空のパスを持つアップロードされたファイルである。
複雑な条件付き禁止ロジックが必要な場合は、Rule::prohibitedIfメソッドを利用できます。このメソッドは、ブール値またはクロージャを受け入れます。クロージャが与えられた場合、クロージャはバリデーション対象のフィールドを禁止すべきかどうかを示すためにtrueまたはfalseを返す必要があります。
1use Illuminate\Support\Facades\Validator; 2use Illuminate\Validation\Rule; 3 4Validator::make($request->all(), [ 5 'role_id' => Rule::prohibitedIf($request->user()->is_admin), 6]); 7 8Validator::make($request->all(), [ 9 'role_id' => Rule::prohibitedIf(fn () => $request->user()->is_admin),10]);
prohibited_unless:anotherfield,value,...
anotherfieldフィールドがいずれかのvalueと等しくない限り、バリデーション対象のフィールドは存在しないか空でなければなりません。フィールドが「空」であると見なされるのは、以下の基準のいずれかを満たす場合です。
- 値が
nullである。 - 値が空の文字列である。
- 値が空の配列または空の
Countableオブジェクトである。 - 値が空のパスを持つアップロードされたファイルである。
prohibits:anotherfield,...
バリデーション対象のフィールドが存在し、空でない場合、anotherfieldのすべてのフィールドは存在しないか空でなければなりません。フィールドが「空」であると見なされるのは、以下の基準のいずれかを満たす場合です。
- 値が
nullである。 - 値が空の文字列である。
- 値が空の配列または空の
Countableオブジェクトである。 - 値が空のパスを持つアップロードされたファイルである。
regex:pattern
バリデーション対象のフィールドは、指定された正規表現に一致しなければなりません。
内部的に、このルールはPHPのpreg_match関数を使用します。指定するパターンは、preg_matchで要求されるのと同じ書式に従う必要があり、したがって有効なデリミタも含まれている必要があります。例:'email' => 'regex:/^.+@.+$/i'。
regex / not_regexパターンを使用する場合、特に正規表現に|文字が含まれている場合は、|デリミタを使用する代わりにルールを配列で指定する必要がある場合があります。
required
バリデーション対象のフィールドは入力データに存在し、かつ空であってはなりません。フィールドが「空」であると見なされるのは、以下の基準のいずれかを満たす場合です。
- 値が
nullである。 - 値が空の文字列である。
- 値が空の配列または空の
Countableオブジェクトである。 - 値がパスのないアップロードされたファイルである。
required_if:anotherfield,value,...
anotherfieldフィールドがいずれかのvalueと等しい場合、バリデーション対象のフィールドは存在し、かつ空であってはなりません。
required_ifルールに対してより複雑な条件を構築したい場合は、Rule::requiredIfメソッドを使用できます。このメソッドはブール値またはクロージャを受け入れます。クロージャが渡された場合、クロージャはバリデーション対象のフィールドが必要かどうかを示すためにtrueまたはfalseを返す必要があります。
1use Illuminate\Support\Facades\Validator; 2use Illuminate\Validation\Rule; 3 4Validator::make($request->all(), [ 5 'role_id' => Rule::requiredIf($request->user()->is_admin), 6]); 7 8Validator::make($request->all(), [ 9 'role_id' => Rule::requiredIf(fn () => $request->user()->is_admin),10]);
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と等しくない限り、バリデーション対象のフィールドは存在し、かつ空であってはなりません。これは、valueがnullでない限り、anotherfieldがリクエストデータに存在しなければならないことも意味します。valueがnullの場合(required_unless:name,null)、比較フィールドがnullであるか、比較フィールドがリクエストデータに存在しない限り、バリデーション対象のフィールドは必須となります。
required_with:foo,bar,...
バリデーション対象のフィールドは、他の指定されたフィールドのいずれかが存在し、かつ空でない場合にのみ、存在し、かつ空であってはなりません。
required_with_all:foo,bar,...
バリデーション対象のフィールドは、他の指定されたフィールドがすべて存在し、かつ空でない場合にのみ、存在し、かつ空であってはなりません。
required_without:foo,bar,...
バリデーション対象のフィールドは、他の指定されたフィールドのいずれかが空であるか存在しない場合にのみ、存在し、かつ空であってはなりません。
required_without_all:foo,bar,...
バリデーション対象のフィールドは、他の指定されたフィールドがすべて空であるか存在しない場合にのみ、存在し、かつ空であってはなりません。
required_array_keys:foo,bar,...
バリデーション対象のフィールドは配列であり、少なくとも指定されたキーを含んでいなければなりません。
same:field
指定されたfieldは、バリデーション対象のフィールドと一致しなければなりません。
size:value
バリデーション対象のフィールドは、指定されたvalueと一致するサイズでなければなりません。文字列データの場合、valueは文字数に対応します。数値データの場合、valueは指定された整数値に対応します(属性にはnumericまたはintegerルールも必要です)。配列の場合、sizeは配列のcountに対応します。ファイルの場合、sizeはキロバイト単位のファイルサイズに対応します。いくつかの例を見てみましょう。
1// Validate that a string is exactly 12 characters long... 2'title' => 'size:12'; 3 4// Validate that a provided integer equals 10... 5'seats' => 'integer|size:10'; 6 7// Validate that an array has exactly 5 elements... 8'tags' => 'array|size:5'; 9 10// Validate that an uploaded file is exactly 512 kilobytes...11'image' => 'file|size:512';
starts_with:foo,bar,...
バリデーション対象のフィールドは、指定された値のいずれかで始まらなければなりません。
string
バリデーション対象のフィールドは文字列でなければなりません。フィールドがnullであることも許可したい場合は、フィールドにnullableルールを割り当てるべきです。
timezone
バリデーション対象のフィールドは、DateTimeZone::listIdentifiersメソッドによる有効なタイムゾーン識別子でなければなりません。
DateTimeZone::listIdentifiersメソッドが受け入れる引数は、このバリデーションルールにも提供できます。
1'timezone' => 'required|timezone:all';2 3'timezone' => 'required|timezone:Africa';4 5'timezone' => 'required|timezone:per_country,US';
unique:table,column
バリデーション対象のフィールドは、指定されたデータベーステーブル内に存在してはなりません。
カスタムテーブル/カラム名の指定
テーブル名を直接指定する代わりに、テーブル名を決定するために使用するEloquentモデルを指定することもできます。
1'email' => 'unique:App\Models\User,email_address'
columnオプションを使用して、フィールドに対応するデータベースカラムを指定できます。columnオプションが指定されていない場合、バリデーション対象のフィールドの名前が使用されます。
1'email' => 'unique:users,email_address'
カスタムデータベース接続の指定
時々、バリデータによって行われるデータベースクエリにカスタム接続を設定する必要がある場合があります。これを実現するには、接続名をテーブル名の前に追加します。
1'email' => 'unique:connection.users,email_address'
Uniqueルールで特定のIDを無視させる
一意性のバリデーション中に特定のIDを無視したい場合があります。たとえば、ユーザーの名前、メールアドレス、場所を含む「プロファイル更新」画面を考えてみましょう。メールアドレスが一意であることを確認したいでしょう。しかし、ユーザーがメールフィールドではなく名前フィールドのみを変更した場合、ユーザーは既に問題のメールアドレスの所有者であるため、バリデーションエラーがスローされることは望ましくありません。
バリデータにユーザーのIDを無視するように指示するには、Ruleクラスを使用してルールを流暢に定義します。この例では、ルールを|文字で区切る代わりに、バリデーションルールを配列として指定します。
1use Illuminate\Support\Facades\Validator;2use Illuminate\Validation\Rule;3 4Validator::make($data, [5 'email' => [6 'required',7 Rule::unique('users')->ignore($user->id),8 ],9]);
ユーザーが制御するリクエスト入力をignoreメソッドに渡すべきではありません。代わりに、Eloquentモデルインスタンスからの自動インクリメントIDやUUIDなど、システムで生成された一意のIDのみを渡すべきです。さもないと、アプリケーションはSQLインジェクション攻撃に対して脆弱になります。
モデルキーの値をignoreメソッドに渡す代わりに、モデルインスタンス全体を渡すこともできます。Laravelはモデルからキーを自動的に抽出します。
1Rule::unique('users')->ignore($user)
テーブルがid以外の主キーカラム名を使用している場合、ignoreメソッドを呼び出す際にカラムの名前を指定できます。
1Rule::unique('users')->ignore($user->id, 'user_id')
デフォルトでは、uniqueルールはバリデーション対象の属性の名前と一致するカラムの一意性をチェックします。ただし、uniqueメソッドの2番目の引数として異なるカラム名を渡すことができます。
1Rule::unique('users', 'email_address')->ignore($user->id)
追加のWhere句の追加
whereメソッドを使用してクエリをカスタマイズすることで、追加のクエリ条件を指定できます。たとえば、クエリの範囲をaccount_idカラムの値が1のレコードのみを検索するようにスコープするクエリ条件を追加しましょう。
1'email' => Rule::unique('users')->where(fn (Builder $query) => $query->where('account_id', 1))
一意性チェックでソフトデリートされたレコードを無視する
デフォルトでは、uniqueルールは一意性を判断する際にソフトデリートされたレコードを含みます。一意性チェックからソフトデリートされたレコードを除外するには、withoutTrashedメソッドを呼び出すことができます。
1Rule::unique('users')->withoutTrashed();
モデルがソフトデリートされたレコードにdeleted_at以外のカラム名を使用している場合は、withoutTrashedメソッドを呼び出す際にそのカラム名を指定できます。
1Rule::unique('users')->withoutTrashed('was_deleted_at');
uppercase
バリデーション対象のフィールドは、大文字でなければなりません。
url
バリデーション対象のフィールドは、有効なURLでなければなりません。
有効と見なされるべきURLプロトコルを指定したい場合は、バリデーションルールのパラメータとしてプロトコルを渡すことができます。
1'url' => 'url:http,https',2 3'game' => 'url:minecraft,steam',
ulid
バリデーション対象のフィールドは、有効なUniversally Unique Lexicographically Sortable Identifier(ULID)でなければなりません。
uuid
バリデーション対象のフィールドは、有効なRFC 9562(バージョン1、3、4、5、6、7、または8)のUniversally Unique Identifier(UUID)でなければなりません。
指定されたUUIDがバージョンごとのUUID仕様に一致することも検証できます。
1'uuid' => 'uuid:4'
ルールの条件付き追加
フィールドが特定の値を持つ場合にバリデーションをスキップする
別のフィールドが特定の価を持つ場合に、特定のフィールドをバリデーションしたくない場合があります。これは、exclude_ifバリデーションルールを使用して実現できます。この例では、has_appointmentフィールドの値がfalseの場合、appointment_dateおよびdoctor_nameフィールドはバリデーションされません。
1use Illuminate\Support\Facades\Validator;2 3$validator = Validator::make($data, [4 'has_appointment' => 'required|boolean',5 'appointment_date' => 'exclude_if:has_appointment,false|required|date',6 'doctor_name' => 'exclude_if:has_appointment,false|required|string',7]);
あるいは、exclude_unlessルールを使用して、別のフィールドが特定の値を持たない限り、特定のフィールドをバリデーションしないようにすることもできます。
1$validator = Validator::make($data, [2 'has_appointment' => 'required|boolean',3 'appointment_date' => 'exclude_unless:has_appointment,true|required|date',4 'doctor_name' => 'exclude_unless:has_appointment,true|required|string',5]);
存在する場合のバリデーション
状況によっては、バリデーション対象のデータにそのフィールドが存在する場合にのみ、フィールドに対してバリデーションチェックを実行したい場合があります。これをすばやく実現するには、ルールリストにsometimesルールを追加します。
1$validator = Validator::make($data, [2 'email' => 'sometimes|required|email',3]);
上記の例では、emailフィールドは$data配列に存在する場合にのみバリデーションされます。
常に存在するべきだが空である可能性のあるフィールドをバリデーションしようとしている場合は、オプションフィールドに関するこの注意を確認してください。
複雑な条件付きバリデーション
より複雑な条件付きロジックに基づいてバリデーションルールを追加したい場合があります。たとえば、別のフィールドが100より大きい値を持つ場合にのみ、特定のフィールドを必須にしたい場合があります。または、別のフィールドが存在する場合にのみ、2つのフィールドに特定の価を持たせる必要があるかもしれません。これらのバリデーションルールの追加は、面倒である必要はありません。まず、決して変更されない静的なルールでValidatorインスタンスを作成します。
1use Illuminate\Support\Facades\Validator;2 3$validator = Validator::make($request->all(), [4 'email' => 'required|email',5 'games' => 'required|numeric',6]);
私たちのウェブアプリケーションがゲームコレクター向けであると仮定しましょう。ゲームコレクターが私たちのアプリケーションに登録し、100本以上のゲームを所有している場合、なぜそんなに多くのゲームを所有しているのか説明してもらいたいとします。たとえば、彼らはゲームの再販店を経営しているのかもしれませんし、単にゲームを集めるのが好きなのかもしれません。この要件を条件付きで追加するには、Validatorインスタンスのsometimesメソッドを使用できます。
1use Illuminate\Support\Fluent;2 3$validator->sometimes('reason', 'required|max:500', function (Fluent $input) {4 return $input->games >= 100;5});
sometimesメソッドに渡される最初の引数は、条件付きでバリデーションするフィールドの名前です。2番目の引数は、追加したいルールのリストです。3番目の引数として渡されるクロージャがtrueを返した場合、ルールが追加されます。このメソッドにより、複雑な条件付きバリデーションを簡単に構築できます。一度に複数のフィールドに対して条件付きバリデーションを追加することもできます。
1$validator->sometimes(['reason', 'cost'], 'required', function (Fluent $input) {2 return $input->games >= 100;3});
クロージャに渡される$inputパラメータはIlluminate\Support\Fluentのインスタンスであり、バリデーション対象の入力やファイルにアクセスするために使用できます。
複雑な条件付き配列バリデーション
インデックスがわからない同じネストされた配列内の別のフィールドに基づいてフィールドを検証したい場合があります。このような状況では、クロージャが2番目の引数を受け取ることを許可できます。これは、検証中の配列の現在の個々の項目になります。
1$input = [ 2 'channels' => [ 3 [ 4 'type' => 'email', 6 ], 7 [ 8 'type' => 'url', 9 'address' => 'https://example.com',10 ],11 ],12];13 14$validator->sometimes('channels.*.address', 'email', function (Fluent $input, Fluent $item) {15 return $item->type === 'email';16});17 18$validator->sometimes('channels.*.address', 'url', function (Fluent $input, Fluent $item) {19 return $item->type !== 'email';20});
クロージャに渡される$inputパラメータと同様に、属性データが配列の場合、$itemパラメータはIlluminate\Support\Fluentのインスタンスです。それ以外の場合は文字列です。
配列のバリデーション
arrayバリデーションルールのドキュメントで説明されているように、arrayルールは許可された配列キーのリストを受け入れます。配列内に他のキーが存在する場合、バリデーションは失敗します。
1use Illuminate\Support\Facades\Validator; 2 3$input = [ 4 'user' => [ 5 'name' => 'Taylor Otwell', 6 'username' => 'taylorotwell', 7 'admin' => true, 8 ], 9];10 11Validator::make($input, [12 'user' => 'array:name,username',13]);
一般的に、配列内に存在することが許可されている配列キーは常に指定すべきです。そうしないと、バリデータのvalidateおよびvalidatedメソッドは、他のネストされた配列バリデーションルールによって検証されなかったキーであっても、配列とそのすべてのキーを含むすべての検証済みデータを返します。
ネストした配列入力のバリデーション
ネストされた配列ベースのフォーム入力フィールドのバリデーションは、面倒である必要はありません。配列内の属性をバリデーションするために「ドット記法」を使用できます。たとえば、受信HTTPリクエストにphotos[profile]フィールドが含まれている場合、次のようにバリデーションできます。
1use Illuminate\Support\Facades\Validator;2 3$validator = Validator::make($request->all(), [4 'photos.profile' => 'required|image',5]);
配列の各要素をバリデーションすることもできます。たとえば、指定された配列入力フィールドの各メールが一意であることをバリデーションするには、次のようにします。
1$validator = Validator::make($request->all(), [2 'person.*.email' => 'email|unique:users',3 'person.*.first_name' => 'required_with:person.*.last_name',4]);
同様に、言語ファイルでカスタムバリデーションメッセージを指定する際に*文字を使用でき、配列ベースのフィールドに単一のバリデーションメッセージを簡単に使用できます。
1'custom' => [2 'person.*.email' => [3 'unique' => 'Each person must have a unique email address',4 ]5],
ネストされた配列データへのアクセス
バリデーションルールを属性に割り当てる際、ネストした配列要素の値にアクセスする必要がある場合があります。これは、Rule::forEachメソッドを使用して実現できます。forEachメソッドは、バリデーション対象の配列属性の各イテレーションで呼び出されるクロージャを受け入れ、その属性の値と、明示的で完全に展開された属性名を受け取ります。クロージャは、配列要素に割り当てるルールの配列を返す必要があります。
1use App\Rules\HasPermission; 2use Illuminate\Support\Facades\Validator; 3use Illuminate\Validation\Rule; 4 5$validator = Validator::make($request->all(), [ 6 'companies.*.id' => Rule::forEach(function (string|null $value, string $attribute) { 7 return [ 8 Rule::exists(Company::class, 'id'), 9 new HasPermission('manage-company', $value),10 ];11 }),12]);
エラーメッセージのインデックスと位置
配列をバリデーションする際、アプリケーションで表示されるエラーメッセージ内で、バリデーションに失敗した特定の項目のインデックスや位置を参照したい場合があります。これを実現するには、カスタムバリデーションメッセージ内に:index(0から始まる)と:position(1から始まる)のプレースホルダーを含めることができます。
1use Illuminate\Support\Facades\Validator; 2 3$input = [ 4 'photos' => [ 5 [ 6 'name' => 'BeachVacation.jpg', 7 'description' => 'A photo of my beach vacation!', 8 ], 9 [10 'name' => 'GrandCanyon.jpg',11 'description' => '',12 ],13 ],14];15 16Validator::validate($input, [17 'photos.*.description' => 'required',18], [19 'photos.*.description.required' => 'Please describe photo #:position.',20]);
上記の例では、バリデーションは失敗し、ユーザーには「Please describe photo #2(写真#2の説明を記入してください)」というエラーが表示されます。
必要であれば、second-index、second-position、third-index、third-positionなどを介して、より深くネストしたインデックスや位置を参照することもできます。
1'photos.*.attributes.*.string' => 'Invalid attribute for photo #:second-position.',
ファイルのバリデーション
Laravelは、アップロードされたファイルをバリデーションするために使用できる、mimes、image、min、maxなどの様々なバリデーションルールを提供しています。ファイルをバリデーションする際にこれらのルールを個別に指定することも自由ですが、Laravelは便利に使える、流れるような(fluent)ファイルバリデーションルールビルダーも提供しています。
1use Illuminate\Support\Facades\Validator; 2use Illuminate\Validation\Rules\File; 3 4Validator::validate($input, [ 5 'attachment' => [ 6 'required', 7 File::types(['mp3', 'wav']) 8 ->min(1024) 9 ->max(12 * 1024),10 ],11]);
ファイルタイプのバリデーション
typesメソッドを呼び出す際には拡張子を指定するだけでよいのですが、このメソッドは実際には、ファイルの内容を読み取ってMIMEタイプを推測することで、ファイルのMIMEタイプをバリデーションします。MIMEタイプとそれに対応する拡張子の完全なリストは、次の場所で確認できます。
https://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types
ファイルサイズのバリデーション
便宜上、最小および最大のファイルサイズは、ファイルサイズの単位を示す接尾辞を付けた文字列として指定できます。kb、mb、gb、tbの接尾辞がサポートされています。
1File::types(['mp3', 'wav'])2 ->min('1kb')3 ->max('10mb');
画像ファイルのバリデーション
アプリケーションがユーザーからアップロードされた画像を受け入れる場合、Fileルールのimageコンストラクタメソッドを使用して、バリデーション対象のファイルが画像(jpg、jpeg、png、bmp、gif、またはwebp)であることを保証できます。
さらに、dimensionsルールを使用して、画像のサイズを制限することができます。
1use Illuminate\Support\Facades\Validator; 2use Illuminate\Validation\Rule; 3use Illuminate\Validation\Rules\File; 4 5Validator::validate($input, [ 6 'photo' => [ 7 'required', 8 File::image() 9 ->min(1024)10 ->max(12 * 1024)11 ->dimensions(Rule::dimensions()->maxWidth(1000)->maxHeight(500)),12 ],13]);
画像の寸法のバリデーションに関するより詳しい情報は、dimensionsルールのドキュメントで確認できます。
デフォルトでは、XSS脆弱性の可能性があるため、imageルールはSVGファイルを許可しません。SVGファイルを許可する必要がある場合は、imageルールにallowSvg: trueを渡すことができます:File::image(allowSvg: true)。
画像サイズのバリデーション
画像のサイズ(寸法)をバリデーションすることもできます。例えば、アップロードされた画像が幅1000ピクセル以上、高さ500ピクセル以上であることをバリデーションするには、dimensionsルールを使用できます。
1use Illuminate\Validation\Rule;2use Illuminate\Validation\Rules\File;3 4File::image()->dimensions(5 Rule::dimensions()6 ->maxWidth(1000)7 ->maxHeight(500)8)
画像の寸法のバリデーションに関するより詳しい情報は、dimensionsルールのドキュメントで確認できます。
パスワードのバリデーション
パスワードが適切なレベルの複雑さを持っていることを保証するために、LaravelのPasswordルールオブジェクトを使用できます。
1use Illuminate\Support\Facades\Validator;2use Illuminate\Validation\Rules\Password;3 4$validator = Validator::make($request->all(), [5 'password' => ['required', 'confirmed', Password::min(8)],6]);
Passwordルールオブジェクトを使用すると、パスワードに少なくとも1つの文字、数字、記号、または大文字小文字が混在した文字が必要であるといった、アプリケーションのパスワードの複雑さの要件を簡単にカスタマイズできます。
1// Require at least 8 characters... 2Password::min(8) 3 4// Require at least one letter... 5Password::min(8)->letters() 6 7// Require at least one uppercase and one lowercase letter... 8Password::min(8)->mixedCase() 9 10// Require at least one number...11Password::min(8)->numbers()12 13// Require at least one symbol...14Password::min(8)->symbols()
さらに、uncompromisedメソッドを使用して、公開されたパスワードデータ侵害漏洩でパスワードが侵害されていないことを確認できます。
1Password::min(8)->uncompromised()
内部的に、Passwordルールオブジェクトはk-Anonymityモデルを使用して、ユーザーのプライバシーやセキュリティを犠牲にすることなく、haveibeenpwned.comサービスを介してパスワードが漏洩したかどうかを判断します。
デフォルトでは、データ漏洩でパスワードが1回でも出現した場合、それは侵害されたと見なされます。この閾値は、uncompromisedメソッドの最初の引数を使用してカスタマイズできます。
1// Ensure the password appears less than 3 times in the same data leak...2Password::min(8)->uncompromised(3);
もちろん、上記の例のすべてのメソッドをチェーン(連結)させることができます。
1Password::min(8)2 ->letters()3 ->mixedCase()4 ->numbers()5 ->symbols()6 ->uncompromised()
デフォルトのパスワードルールを定義する
アプリケーションの一箇所でパスワードのデフォルトのバリデーションルールを指定すると便利な場合があります。これは、クロージャを受け入れるPassword::defaultsメソッドを使用して簡単に実現できます。defaultsメソッドに渡されたクロージャは、Passwordルールのデフォルト設定を返す必要があります。通常、defaultsルールは、アプリケーションのサービスプロバイダのいずれかのbootメソッド内で呼び出すべきです。
1use Illuminate\Validation\Rules\Password; 2 3/** 4 * Bootstrap any application services. 5 */ 6public function boot(): void 7{ 8 Password::defaults(function () { 9 $rule = Password::min(8);10 11 return $this->app->isProduction()12 ? $rule->mixedCase()->uncompromised()13 : $rule;14 });15}
そして、バリデーション中の特定のパスワードにデフォルトルールを適用したい場合は、引数なしでdefaultsメソッドを呼び出すことができます。
1'password' => ['required', Password::defaults()],
場合によっては、デフォルトのパスワードバリデーションルールに追加のバリデーションルールを加えたいことがあるかもしれません。これを実現するには、rulesメソッドを使用できます。
1use App\Rules\ZxcvbnRule;2 3Password::defaults(function () {4 $rule = Password::min(8)->rules([new ZxcvbnRule]);5 6 // ...7});
カスタムバリデーションルール
ルールオブジェクトの使用
Laravelはさまざまな便利なバリデーションルールを提供していますが、独自のルールをいくつか指定したい場合もあるでしょう。カスタムバリデーションルールを登録する一つの方法は、ルールオブジェクトを使用することです。新しいルールオブジェクトを生成するには、make:rule Artisanコマンドを使用できます。このコマンドを使って、文字列が大文字であることを検証するルールを生成してみましょう。Laravelは新しいルールをapp/Rulesディレクトリに配置します。このディレクトリが存在しない場合、Laravelはルールを作成するためにArtisanコマンドを実行する際に、このディレクトリを作成します。
1php artisan make:rule Uppercase
ルールが作成されたら、その振る舞いを定義する準備が整います。ルールオブジェクトには、validateという1つのメソッドが含まれています。このメソッドは、属性名、その値、そしてバリデーションエラーメッセージと共に失敗時に呼び出すべきコールバックを受け取ります。
1<?php 2 3namespace App\Rules; 4 5use Closure; 6use Illuminate\Contracts\Validation\ValidationRule; 7 8class Uppercase implements ValidationRule 9{10 /**11 * Run the validation rule.12 */13 public function validate(string $attribute, mixed $value, Closure $fail): void14 {15 if (strtoupper($value) !== $value) {16 $fail('The :attribute must be uppercase.');17 }18 }19}
ルールが定義されたら、他のバリデーションルールと一緒にルールオブジェクトのインスタンスを渡すことで、それをバリデータにアタッチ(追加)できます。
1use App\Rules\Uppercase;2 3$request->validate([4 'name' => ['required', 'string', new Uppercase],5]);
バリデーションメッセージの翻訳
$failクロージャにリテラルなエラーメッセージを提供する代わりに、翻訳文字列キーを提供し、Laravelにエラーメッセージを翻訳させることもできます。
1if (strtoupper($value) !== $value) {2 $fail('validation.uppercase')->translate();3}
必要に応じて、translateメソッドの第1引数と第2引数として、プレースホルダの置換と優先言語を提供できます。
1$fail('validation.location')->translate([2 'value' => $this->value,3], 'fr')
追加データへのアクセス
カスタムバリデーションルールクラスが、バリデーション中の他のすべてのデータにアクセスする必要がある場合、ルールクラスはIlluminate\Contracts\Validation\DataAwareRuleインターフェースを実装することができます。このインターフェースは、クラスにsetDataメソッドを定義することを要求します。このメソッドは、(バリデーションが進む前に)バリデーション対象のすべてのデータと共に、Laravelによって自動的に呼び出されます。
1<?php 2 3namespace App\Rules; 4 5use Illuminate\Contracts\Validation\DataAwareRule; 6use Illuminate\Contracts\Validation\ValidationRule; 7 8class Uppercase implements DataAwareRule, ValidationRule 9{10 /**11 * All of the data under validation.12 *13 * @var array<string, mixed>14 */15 protected $data = [];16 17 // ...18 19 /**20 * Set the data under validation.21 *22 * @param array<string, mixed> $data23 */24 public function setData(array $data): static25 {26 $this->data = $data;27 28 return $this;29 }30}
または、バリデーションルールがバリデーションを実行しているバリデータインスタンスへのアクセスを必要とする場合は、ValidatorAwareRuleインターフェースを実装できます。
1<?php 2 3namespace App\Rules; 4 5use Illuminate\Contracts\Validation\ValidationRule; 6use Illuminate\Contracts\Validation\ValidatorAwareRule; 7use Illuminate\Validation\Validator; 8 9class Uppercase implements ValidationRule, ValidatorAwareRule10{11 /**12 * The validator instance.13 *14 * @var \Illuminate\Validation\Validator15 */16 protected $validator;17 18 // ...19 20 /**21 * Set the current validator.22 */23 public function setValidator(Validator $validator): static24 {25 $this->validator = $validator;26 27 return $this;28 }29}
クロージャの使用
アプリケーション全体で一度だけカスタムルールの機能が必要な場合は、ルールオブジェクトの代わりにクロージャを使用できます。クロージャは、属性の名前、属性の値、およびバリデーションが失敗した場合に呼び出されるべき$failコールバックを受け取ります。
1use Illuminate\Support\Facades\Validator; 2use Closure; 3 4$validator = Validator::make($request->all(), [ 5 'title' => [ 6 'required', 7 'max:255', 8 function (string $attribute, mixed $value, Closure $fail) { 9 if ($value === 'foo') {10 $fail("The {$attribute} is invalid.");11 }12 },13 ],14]);
暗黙のルール
デフォルトでは、バリデーション対象の属性が存在しないか、空の文字列を含んでいる場合、カスタムルールを含む通常のバリデーションルールは実行されません。例えば、uniqueルールは空の文字列に対しては実行されません。
1use Illuminate\Support\Facades\Validator;2 3$rules = ['name' => 'unique:users,name'];4 5$input = ['name' => ''];6 7Validator::make($input, $rules)->passes(); // true
属性が空の場合でもカスタムルールを実行させるには、そのルールが属性が必須であることを暗示(imply)する必要があります。新しい暗黙的な(implicit)ルールオブジェクトを素早く生成するには、--implicitオプションを付けてmake:rule Artisanコマンドを使用できます。
1php artisan make:rule Uppercase --implicit
「暗黙的な(implicit)」ルールは、属性が必須であることを*暗示する*だけです。それが実際に欠落している、または空の属性を無効にするかどうかは、あなた次第です。