- はじめに
- バリデーション クイックスタート
- フォームリクエストバリデーション
- バリデーターの手動作成
- バリデート済み入力の操作
- エラーメッセージの操作
- 利用可能なバリデーションルール
- 条件付きルールの追加
- 配列のバリデーション
- ファイルのバリデーション
- パスワードのバリデーション
- カスタムバリデーションルール
#はじめに
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
{
/**
* 新しいブログ投稿作成フォームを表示します。
*/
public function create(): View
{
return view('post.create');
}
/**
* 新しいブログ投稿を保存します。
*/
public function store(Request $request): RedirectResponse
{
// ブログ投稿をバリデートして保存...
$post = /** ... */
return to_route('post.show', ['post' => $post->id]);
}
}
#バリデーションロジックの記述
store メソッドに新しいブログ投稿をバリデートするロジックを記述しましょう。Illuminate\Http\Request オブジェクトが提供する validate メソッドを使います。バリデーションルールが通れば通常通りコードが実行されますが、失敗すると Illuminate\Validation\ValidationException 例外がスローされ、適切なエラーレスポンスが自動的にユーザーに返されます。
従来のHTTPリクエストでバリデーションに失敗した場合、前のURLへリダイレクトされます。XHRリクエストの場合は、バリデーションエラーメッセージを含むJSONレスポンスが返されます。
validate メソッドの理解を深めるために、store メソッドに戻りましょう:
/**
* 新しいブログ投稿を保存します。
*/
public function store(Request $request): RedirectResponse
{
$validated = $request->validate([
'title' => 'required|unique:posts|max:255',
'body' => 'required',
]);
// ブログ投稿は有効です...
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 ミドルウェアによって $errors 変数がアプリケーションのすべてのビューと共有されます。これは web ミドルウェアグループによって提供されます。このミドルウェアが適用されると、ビュー内では常に $errors 変数が利用可能になり、$errors 変数が常に定義されていると仮定して安全に使用できます。$errors 変数は Illuminate\Support\MessageBag のインスタンスになります。このオブジェクトの操作について詳しくは、ドキュメントを参照してください。
したがって、例ではバリデーション失敗時にユーザーはコントローラーの create メソッドにリダイレクトされ、ビューでエラーメッセージを表示できます:
<!-- /resources/views/post/create.blade.php -->
<h1>Create Post</h1>
@if ($errors->any())
<div class="alert alert-danger">
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
<!-- 投稿作成フォーム -->
#エラーメッセージのカスタマイズ
Laravel の組み込みバリデーションルールには、それぞれアプリケーションの lang/en/validation.php ファイルにエラーメッセージが用意されています。lang ディレクトリがない場合は、lang:publish Artisan コマンドで作成できます。
lang/en/validation.php ファイルには各バリデーションルールの翻訳エントリがあり、アプリケーションの要件に応じて自由に変更・修正できます。
また、このファイルを他の言語ディレクトリにコピーして、アプリケーションの言語に合わせてメッセージを翻訳することも可能です。Laravel のローカリゼーションについては、ローカリゼーションのドキュメントを参照してください。
デフォルトでは、Laravel アプリケーションのスケルトンには lang ディレクトリが含まれていません。Laravel の言語ファイルをカスタマイズしたい場合は、lang:publish Artisan コマンドで公開してください。
#XHRリクエストとバリデーション
この例では従来のフォームを使ってデータを送信しましたが、多くのアプリケーションはJavaScriptを使ったフロントエンドからXHRリクエストを受け取ります。XHRリクエストで validate メソッドを使うと、Laravel はリダイレクトレスポンスを生成しません。代わりに、すべてのバリデーションエラーを含むJSONレスポンスを生成し、HTTPステータスコード422で返します。
#@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 はアプリケーションのグローバルミドルウェアスタックに TrimStrings と ConvertEmptyStringsToNull ミドルウェアを含めています。これらのミドルウェアは App\Http\Kernel クラスによってスタックに登録されています。そのため、バリデーターが 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\Rule|array|string>
*/
public function rules(): array
{
return [
'title' => 'required|unique:posts|max:255',
'body' => 'required',
];
}
rules メソッドのシグネチャに必要な依存をタイプヒントとして指定できます。Laravel の サービスコンテナ により自動的に解決されます。
では、バリデーションルールはどのように評価されるのでしょうか?コントローラーのメソッドでリクエストをタイプヒントするだけです。フォームリクエストはコントローラーメソッドが呼ばれる前にバリデートされるため、コントローラーにバリデーションロジックを記述する必要がありません:
/**
* Store a new blog post.
*/
public function store(StorePostRequest $request): RedirectResponse
{
// 受信したリクエストは有効です...
// バリデート済みの入力データを取得...
$validated = $request->validated();
// バリデート済みの入力データの一部を取得...
$validated = $request->safe()->only(['name', 'email']);
$validated = $request->safe()->except(['name', 'email']);
// ブログ投稿を保存...
return redirect('/posts');
}
バリデーションに失敗すると、ユーザーを前のページにリダイレクトするレスポンスが生成されます。エラーはセッションにフラッシュされ、表示に利用可能です。リクエストが XHR の場合は、422 ステータスコードの HTTP レスポンスが返され、バリデーションエラーの JSON 表現が含まれます。
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;
}
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();
}
// バリデート済みの入力を取得...
$validated = $validator->validated();
// バリデート済みの入力の一部を取得...
$validated = $validator->safe()->only(['name', 'email']);
$validated = $validator->safe()->except(['name', 'email']);
// ブログ投稿を保存...
return redirect('/posts');
}
}
make メソッドに渡される最初の引数はバリデーション対象のデータです。2番目の引数は、そのデータに適用するバリデーションルールの配列です。
リクエストのバリデーションが失敗したかどうかを判定した後、withErrors メソッドを使ってエラーメッセージをセッションにフラッシュできます。このメソッドを使うと、リダイレクト後に $errors 変数が自動的にビューに共有され、ユーザーにエラーを簡単に表示できます。withErrors メソッドはバリデーター、MessageBag、または PHP の array を受け取れます。
#最初のバリデーション失敗で停止する
stopOnFirstFailure メソッドは、バリデーターに対して、1つでもバリデーション失敗が発生した時点で全ての属性のバリデーションを停止するよう指示します:
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');
#名前付きエラーバッグ
1ページに複数のフォームがある場合、バリデーションエラーを含む 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 インスタンスは配列のようにイテレートやアクセスが可能です:
// バリデーション済みデータをイテレートできます...
foreach ($request->safe() as $key => $value) {
// ...
}
// バリデーション済みデータを配列のようにアクセスできます...
$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のローカリゼーションについて詳しくは、ローカリゼーションのドキュメントを参照してください。
デフォルトでは、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',
],
デフォルトでは、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'
],
],
デフォルトでは、Laravelのアプリケーションスケルトンに lang ディレクトリは含まれていません。Laravelの言語ファイルをカスタマイズしたい場合は、lang:publish Artisanコマンドで公開してください。
この値を定義すると、バリデーションルールは次のようなエラーメッセージを生成します:
The credit card number field is required when payment type is credit card.
#利用可能なバリデーションルール
以下は利用可能な全てのバリデーションルールとその機能の一覧です:
<style> .collection-method-list > p { columns: 10.8em 3; -moz-columns: 10.8em 3; -webkit-columns: 10.8em 3; } .collection-method-list a { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } </style>Accepted Accepted If Active URL After (Date) After Or Equal (Date) Alpha Alpha Dash Alpha Numeric Array Ascii Bail Before (Date) Before Or Equal (Date) Between Boolean Confirmed Current Password Date Date Equals Date Format Decimal Declined Declined If Different Digits Digits Between Dimensions (Image Files) Distinct Doesnt Start With Doesnt End With Email Ends With Enum Exclude Exclude If Exclude Unless Exclude With Exclude Without Exists (Database) Extensions File Filled Greater Than Greater Than Or Equal Hex Color Image (File) In In Array Integer IP Address JSON Less Than Less Than Or Equal Lowercase MAC Address Max Max Digits MIME Types MIME Type By File Extension Min Min Digits Missing Missing If Missing Unless Missing With Missing With All Multiple Of Not In Not Regex Nullable Numeric Present Present If Present Unless Present With Present With All Prohibited Prohibited If Prohibited Unless Prohibits Regular Expression Required Required If Required If Accepted Required Unless Required With Required With All Required Without Required Without All Required Array Keys Same Size Sometimes Starts With String Timezone Unique (Database) Uppercase URL ULID UUID
#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 のホスト名は、parse_url 関数で抽出されてから dns_get_record に渡されます。
#after:date
検証対象のフィールドは、指定された日付より後の日付でなければなりません。日付は PHP の strtotime 関数に渡され、有効な DateTime インスタンスに変換されます。
'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 範囲(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
検証対象のフィールドは、指定された日付より前または同じ日付でなければなりません。日付は有効なDateTimeインスタンスに変換するためにPHPのstrtotime関数に渡されます。さらに、afterルールと同様に、dateの値として別の検証対象フィールド名を指定することもできます。
#between:min,max
検証対象のフィールドのサイズは、指定された min と max の間(両端含む)でなければなりません。文字列、数値、配列、ファイルは size ルールと同様に評価されます。
#boolean
検証対象のフィールドはブール値にキャスト可能でなければなりません。許容される入力は true、false、1、0、"1"、"0" です。
#confirmed
検証対象のフィールドには、対応する {field}_confirmation フィールドが存在し、値が一致している必要があります。例えば、検証対象が password の場合、password_confirmation フィールドが入力に存在しなければなりません。
#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
検証対象のフィールドは数値であり、指定された小数点以下の桁数を含んでいなければなりません。
// 小数点以下2桁でなければなりません(例: 9.99)...
'price' => 'decimal:2'
// 小数点以下2桁から4桁の間でなければなりません...
'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
検証対象のファイルは、ルールのパラメータで指定された寸法制約を満たす画像でなければなりません。
'avatar' => 'dimensions:min_width=100,min_height=200'
利用可能な制約は、min_width、max_width、min_height、max_height、width、height、ratio です。
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,...
検証対象のフィールドは、指定された値のいずれかで終わってはいけません。
検証対象のフィールドはメールアドレス形式である必要があります。このバリデーションルールはメールアドレスの検証に egulias/email-validator パッケージを使用します。デフォルトでは RFCValidation バリデーターが適用されますが、他の検証スタイルも適用可能です:
'email' => 'email:rfc,dns'
上記の例では RFCValidation と DNSCheckValidation の検証が適用されます。適用可能な検証スタイルの完全なリストは以下の通りです:
rfc:RFCValidationstrict:NoRFCWarningsValidationdns:DNSCheckValidationspoof:SpoofCheckValidationfilter:FilterEmailValidationfilter_unicode:FilterEmailValidation::unicode()
PHPの filter_var 関数を使う filter バリデーターはLaravelに組み込まれており、Laravel 5.8以前のデフォルトのメール検証方法でした。
dns と spoof バリデーターはPHPの intl 拡張モジュールが必要です。
#ends_with:foo,bar,...
検証対象のフィールドは指定された値のいずれかで終わっている必要があります。
#enum
Enum ルールはクラスベースのルールで、検証対象のフィールドが有効なenum値かどうかを検証します。Enum ルールはコンストラクタ引数としてenumの名前を受け取ります。プリミティブ値を検証する場合は、バックドEnumを Enum ルールに渡す必要があります:
use App\Enums\ServerStatus;
use Illuminate\Validation\Rule;
$request->validate([
'status' => [Rule::enum(ServerStatus::class)],
]);
Enum ルールの only と except メソッドを使って、有効とみなすenumケースを制限できます:
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 メソッドが返すリクエストデータから除外されます。value が null の場合(exclude_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) {
return $query->where('account_id', 1);
}),
],
]);
Rule::exists メソッドによって生成される exists ルールが使用するデータベースのカラム名は、exists メソッドの第2引数にカラム名を渡すことで明示的に指定できます:
'state' => Rule::exists('states', 'abbreviation'),
#extensions:foo,bar,...
検証対象のファイルは、指定された拡張子のいずれかである必要があります:
'photo' => ['required', 'extensions:jpg,png'],
#file
検証対象のフィールドは正常にアップロードされたファイルである必要があります。
#filled
検証対象のフィールドは存在する場合、空であってはいけません。
#gt:field
検証対象のフィールドは指定された field または value より大きくなければなりません。両フィールドは同じ型である必要があります。文字列、数値、配列、ファイルは size ルールと同じ基準で評価されます。
#gte:field
検証対象のフィールドは指定された field または value 以上でなければなりません。両フィールドは同じ型である必要があります。文字列、数値、配列、ファイルは 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
検証対象のフィールドは整数である必要があります。
このバリデーションルールは、入力が整数型の変数であることを検証するものではなく、PHP の FILTER_VALIDATE_INT ルールで受け入れられる型であるかどうかのみを確認します。入力が数値であることを検証したい場合は、このルールをnumeric バリデーションルールと組み合わせて使用してください。
#ip
検証対象のフィールドはIPアドレスである必要があります。
#ipv4
検証対象のフィールドはIPv4アドレスである必要があります。
#ipv6
検証対象のフィールドはIPv6アドレスである必要があります。
#json
検証対象のフィールドは有効なJSON文字列である必要があります。
#lt:field
検証対象のフィールドは指定された field より小さくなければなりません。両フィールドは同じ型である必要があります。文字列、数値、配列、ファイルは size ルールと同じ基準で評価されます。
#lte:field
検証対象のフィールドは指定された field 以下でなければなりません。両フィールドは同じ型である必要があります。文字列、数値、配列、ファイルは size ルールと同じ基準で評価されます。
#lowercase
検証対象のフィールドは小文字である必要があります。
#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タイプと対応する拡張子の完全な一覧は以下で確認できます:
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'。
regex / not_regex パターンを使用する場合、特に正規表現に | 文字が含まれる場合は、| 区切りではなく配列でバリデーションルールを指定する必要があることがあります。
#nullable
検証対象のフィールドは null でもかまいません。
#numeric
検証対象のフィールドは 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'。
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_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 はファイルサイズ(キロバイト単位)に対応します。いくつか例を見てみましょう:
// 文字列がちょうど12文字であることを検証...
'title' => 'size:12';
// 整数が10と等しいことを検証...
'seats' => 'integer|size:10';
// 配列がちょうど5要素であることを検証...
'tags' => 'array|size:5';
// アップロードされたファイルがちょうど512キロバイトであることを検証...
'image' => 'file|size:512';
#starts_with:foo,bar,...
検証対象のフィールドは、指定された値のいずれかで始まらなければなりません。
#string
検証対象のフィールドは文字列でなければなりません。null も許容したい場合は、nullable ルールを割り当ててください。
#timezone
検証対象のフィールドは、DateTimeZone::listIdentifiers メソッドに準拠した有効なタイムゾーン識別子でなければなりません。
このバリデーションルールには、DateTimeZone::listIdentifiers メソッド が受け取る引数を指定することもできます:
'timezone' => 'required|timezone:all';
'timezone' => 'required|timezone:Africa';
'timezone' => 'required|timezone:per_country,US';
#unique:table,column
検証対象のフィールドは、指定されたデータベーステーブル内に存在してはいけません。
カスタムテーブル/カラム名の指定:
テーブル名を直接指定する代わりに、テーブル名を決定するために使用する 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),
],
]);
ignore メソッドにユーザーが操作可能なリクエスト入力を渡してはいけません。代わりに、Eloquent モデルインスタンスの自動増分IDや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)のユニバーサルユニーク識別子(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 ルールを追加します:
$v = Validator::make($data, [
'email' => 'sometimes|required|email',
]);
上記の例では、email フィールドが $data 配列に存在する場合にのみバリデーションが実行されます。
常に存在すべきだが空の場合もあるフィールドをバリデートしようとしている場合は、オプションフィールドに関する注意を参照してください。
#複雑な条件付きバリデーション
より複雑な条件に基づいてバリデーションルールを追加したい場合があります。例えば、あるフィールドの値が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;
});
クロージャに渡される $input パラメータは Illuminate\Support\Fluent のインスタンスで、バリデーション対象の入力やファイルにアクセスできます。
#複雑な条件付き配列バリデーション
ネストされた配列の中で、インデックスが不明な別のフィールドに基づいてバリデーションしたい場合があります。このような場合、クロージャに第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' => '各人はユニークなメールアドレスを持つ必要があります',
]
],
#ネストされた配列データへのアクセス
属性にバリデーションルールを割り当てる際に、ネストされた配列要素の値にアクセスする必要がある場合があります。これは Rule::forEach メソッドを使って実現できます。forEach メソッドは、バリデーション対象の配列属性の各イテレーションで呼び出されるクロージャを受け取り、属性の値と完全に展開された属性名を受け取ります。クロージャは配列要素に割り当てるルールの配列を返す必要があります:
use App\Rules\HasPermission;
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;
$validator = Validator::make($request->all(), [
'companies.*.id' => Rule::forEach(function (string|null $value, string $attribute) {
return [
Rule::exists(Company::class, 'id'),
new HasPermission('manage-company', $value),
];
}),
]);
#エラーメッセージのインデックスと位置
配列を検証する際、アプリケーションに表示されるエラーメッセージ内で検証に失敗した特定の項目のインデックスや位置を参照したいことがあります。これを行うには、:index(0から始まります)および:position(1から始まります)プレースホルダをカスタム検証メッセージ内に含めます:
use Illuminate\Support\Facades\Validator;
$input = [
'photos' => [
[
'name' => 'BeachVacation.jpg',
'description' => 'A photo of my beach vacation!',
],
[
'name' => 'GrandCanyon.jpg',
'description' => '',
],
],
];
Validator::validate($input, [
'photos.*.description' => 'required',
], [
'photos.*.description.required' => '写真 #:position の説明を入力してください。',
]);
上記の例ではバリデーションが失敗し、ユーザーには「写真 #2 の説明を入力してください。」というエラーが表示されます。
必要に応じて、second-index、second-position、third-index、third-position など、より深いネストのインデックスや位置を参照できます。
'photos.*.attributes.*.string' => '写真 #:second-position の属性が無効です。',
#ファイルのバリデーション
Laravel は、アップロードされたファイルをバリデートするために mimes、image、min、max などの様々なルールを提供しています。これらのルールを個別に指定しても構いませんが、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)),
],
]);
画像の寸法バリデーションに関する詳細は、dimensions ルールのドキュメントを参照してください。
#ファイルサイズ
利便性のため、最小・最大ファイルサイズはファイルサイズ単位を示す接尾辞付きの文字列で指定できます。kb、mb、gb、tb の接尾辞がサポートされています:
File::image()
->min('1kb')
->max('10mb')
#ファイルタイプ
types メソッドを呼び出す際に拡張子だけを指定すればよいですが、このメソッドは実際にはファイルの内容を読み取り、MIMEタイプを推測して検証します。MIMEタイプと対応する拡張子の完全な一覧は以下のURLで確認できます:
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文字の英字、数字、記号、大小文字混在などの複雑さ要件を簡単にカスタマイズできます:
// 最低8文字を要求...
Password::min(8)
// 少なくとも1文字の英字を要求...
Password::min(8)->letters()
// 少なくとも1文字の大文字と小文字を要求...
Password::min(8)->mixedCase()
// 少なくとも1文字の数字を要求...
Password::min(8)->numbers()
// 少なくとも1文字の記号を要求...
Password::min(8)->symbols()
さらに、uncompromised メソッドを使うと、パスワードが公開されたデータ漏洩で流出していないことを確認できます:
Password::min(8)->uncompromised()
内部的に、Password ルールオブジェクトは k-Anonymity モデルを使用して、ユーザーのプライバシーやセキュリティを損なうことなく、haveibeenpwned.com サービスを通じてパスワードが漏洩しているかどうかを判定します。
デフォルトでは、パスワードがデータ漏洩に少なくとも1回でも登場した場合、そのパスワードは漏洩済みと見なされます。この閾値は uncompromised メソッドの最初の引数でカスタマイズできます。
// 同じデータ漏洩でパスワードが3回未満しか登場しないことを保証する...
Password::min(8)->uncompromised(3);
もちろん、上記の例のすべてのメソッドをチェーンすることも可能です。
Password::min(8)
->letters()
->mixedCase()
->numbers()
->symbols()
->uncompromised()
#デフォルトのパスワードルールの定義
アプリケーションの一箇所でパスワードのデフォルトバリデーションルールを指定しておくと便利です。クロージャを受け取るPassword::defaultsメソッドを使えば、これを簡単に行えます。defaultsメソッドに渡すクロージャは、Passwordルールのデフォルト設定を返す必要があります。通常、defaultsルールはアプリケーションのいずれかのサービスプロバイダのbootメソッド内で呼び出します:
use Illuminate\Validation\Rules\Password;
/**
* アプリケーションサービスのブートストラップ処理。
*/
public function boot(): void
{
Password::defaults(function () {
$rule = Password::min(8);
return $this->app->isProduction()
? $rule->mixedCase()->uncompromised()
: $rule;
});
}
その後、特定のパスワードのバリデーションにデフォルトルールを適用したい場合は、引数なしで defaults メソッドを呼び出せます。
'password' => ['required', Password::defaults()],
時には、デフォルトのパスワードバリデーションルールに追加のルールを付け加えたい場合があります。その場合は rules メソッドを使って実現できます。
use App\Rules\ZxcvbnRule;
Password::defaults(function () {
$rule = Password::min(8)->rules([new ZxcvbnRule]);
// ...
});
#カスタムバリデーションルール
#ルールオブジェクトの使用
Laravel は便利なバリデーションルールを多数提供していますが、独自のルールを指定したい場合もあります。カスタムバリデーションルールを登録する方法の一つがルールオブジェクトの利用です。新しいルールオブジェクトを生成するには、make:rule Artisan コマンドを使います。このコマンドで、文字列が大文字であることを検証するルールを生成してみましょう。Laravel は新しいルールを app/Rules ディレクトリに配置します。このディレクトリが存在しない場合は、コマンド実行時に自動で作成されます。
php artisan make:rule Uppercase
ルールが作成されたら、その振る舞いを定義します。ルールオブジェクトは validate メソッドを1つ持ちます。このメソッドは属性名、値、そしてバリデーション失敗時に呼び出すコールバックを受け取ります。
<?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 メソッドの第1引数にプレースホルダーの置換配列、第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
{
/**
* バリデーション対象のすべてのデータ。
*
* @var array<string, mixed>
*/
protected $data = [];
// ...
/**
* バリデーション対象のデータをセットする。
*
* @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
{
/**
* バリデーターインスタンス。
*
* @var \Illuminate\Validation\Validator
*/
protected $validator;
// ...
/**
* 現在のバリデーターをセットする。
*/
public function setValidator(Validator $validator): static
{
$this->validator = $validator;
return $this;
}
}
クロージャの使用
アプリケーション内で一度だけカスタムルールが必要な場合は、ルールオブジェクトの代わりにクロージャを使えます。クロージャは属性名、属性値、バリデーション失敗時に呼び出す $fail コールバックを受け取ります。
use Illuminate\Support\Facades\Validator;
use Closure;
$validator = Validator::make($request->all(), [
'title' => [
'required',
'max:255',
function (string $attribute, mixed $value, Closure $fail) {
if ($value === 'foo') {
$fail("The {$attribute} is invalid.");
}
},
],
]);
暗黙的ルール
デフォルトでは、バリデーション対象の属性が存在しないか空文字の場合、通常のバリデーションルール(カスタムルールも含む)は実行されません。例えば、unique ルールは空文字に対しては実行されません。
use Illuminate\Support\Facades\Validator;
$rules = ['name' => 'unique:users,name'];
$input = ['name' => ''];
Validator::make($input, $rules)->passes(); // true
カスタムルールを空の属性に対しても実行したい場合、そのルールは属性が必須であることを暗示しなければなりません。新しい暗黙的ルールオブジェクトを素早く生成するには、make:rule Artisan コマンドに --implicit オプションを付けて実行します。
php artisan make:rule Uppercase --implicit
「暗黙的」ルールは属性が必須であることを 暗示 するだけです。実際に属性が欠落または空の場合に無効とするかどうかはあなた次第です。