入門者のためのLaravelのバリデーションとエラーメッセージ

Laravel11に対応した内容に更新しています。
目次
バリデーション(validation)とは
WEBアプリケーションの世界ではユーザが入力フォームで入力した値がアプリケーションにとって妥当な値をチェックすることをバリデーションと呼びます。例えばショッピングサイトから商品を初めて購入した場合は必ず住所の入力が必要となります。入力した郵便番号に漏れがないか郵便番号の桁数が7桁になっているかなどチェックすることをバリデーションといいます。
基本的なバリデーションの動作についてはLaravel5, Laravel6, Laravel7, Laravel8, Laravel9, Laravel10, Laravel11で共通です。またバリデーションという機能はLaravel特有のものではなく他の言語やフレームワークでも利用されているものなのでLaravelでのバリデーションを理解できれば基本的な知識は他でも幅広く活用することができます。バリデーションはアプリケーションの開発者であれば必須の知識となります。
本文書を読み終えるとバリデーションの下記の理解を深めることができます。
- バリデーションとは何か
- Laravelソースコードから実際に実装されているバリデーションを理解
- バリデーションの方法
- バリデーションエラーの表示と表示場所の設定
- バリデーションエラーの日本語化
- カスタムバリデーションの作成方法
バリデーションって難しいの??
バリデーションという言葉を聴き慣れていない人であればバリデーションは非常に難しく複雑なものだと思うかもしれませんがバリデーションの意味を理解することだけであればは非常にシンプルです。入力した値に対してルールを設定し、入力した値がそのルールにパスするか失敗するかチェックを行うだけです。仕組みはシンプルですが、バリデーションが失敗した場合にどのようにユーザに対してメッセージを伝えるかがバリデーションを使いこなす上で重要になります。また各自がルールを作成するとバリデーションコードに漏れやバグが入り込む可能性もあります。そのためLaravelでは頻繁に利用されるルールを事前に準備してくれている上、バリデーションに失敗した場合のエラーの表示機能についても簡単に行えるような仕組みを用意してくれています。

ソースコードの確認
バリデーションの動作を確認する前にLaravelのソースコード(ValidatesAttributes.php)を確認してルールがシンプルであること、実際にどのような処理を行っているのかを見ておきましょう。最もシンプルなルールの一つに入力フォームから送られてきた値が数値がどうかチェックするvalidateNumeric関数というものがあります。実際の数値かどうかのチェック方法は以下の通りis_numeric関数を利用しています。シンプルなルールはこれだけのコードで終わります。これなら入門者の人でも自作できるレベルです。

もしルールにパスしなかった場合(Numericのルールであれば数値以外のものが入力された場合)は、ルール名を利用してメッセージ用のファイルlang¥en¥validation.phpにその名前のルールがあるかチェックを行い、もしその名前がある場合はバリデーションに関するエラーメッセージを保存する入れ物MessageBagに登録しているだけです。MessageBagについては後半に説明を行っています。
Laravel10,11ではデフォルトではlangフォルダは存在しません。langフォルダを作成するためには”php artisan lang:publish”を実行する必要があります。
実行すると/lang/enフォルダがプロジェクトフォルダ直下に作成されます。enフォルダにはauth.php, pagination.php, passwords.php, validation.phpが保存されています。
【補足】
動作確認環境の準備
バリデーションというものがどういうものなのかある程度イメージがつかめたと思うので実際にLaravelを利用しながら理解を深めていきます。バリデーションの基本設定、バリデーションによるエラーメッセージの表示場所を確認するため動作確認環境の構築を行います。
動作検証のデータベースの場合はSQLiteデータベース環境を構築すると簡単です。Laravel11ではプロジェクトを作成すると同時にデータベースを作成するのでこれまでのように別でデータベースを構築する必要がないので楽です。データベースが存在することを前提に動作確認を行います。
postsテーブルの準備
postsテーブルを作成して動作確認の環境を構築します。postsテーブルは、titleとbodyの2つ列から構成されます。
Postモデルとマイグレーションファイルの作成を行います。Postモデルと同時にマイグレーションファイルを作成するためphp artisan make:modelコマンドに-mオプションをつけて実行します。
モデルPost.phpファイルはappディレクトリの下にマイグレーションファイルはdatabase/migrationsディレクトリの下に作成されます。

postsテーブルを作成するマイグレーションファイルにtitle, bodyの列情報を追加します。
postsテーブルのtitle, body列の挿入が行えるようにPost.phpファイルを更新します。
postsテーブルの準備ができたので、php artisan migrateコマンドでpostsテーブルを作成します。
ルーティングの設定
web.phpに以下のルーティングの設定を行います。
Laravel8以降の記述方法
Laravel7までの記述方法
コントローラーの作成
php artisan make:controllerコマンドを使ってPostController.phpの作成を行います。
ルーティングファイルweb.phpで追加したcreateメソッドとstoreメソッドを記述します。createメソッドでは入力フォームを表示するビューファイルを指定して、storeメソッドの中にバリデーションのロジックを記述します。
ビューの作成
入力フォームを表示させるためのビューの作成を行います。resources/views/postディレクトリの下にcreate.blade.phpを行います。
ビューファイルの中身は下記の通りです。
php artisan serveコマンドで開発サーバを起動してブラウザからhttp://127.0.0.1:8000/post/createにアクセスすると作成した入力フォームが表示されます。

バリデーションのメソッドとルール
validateメソッドについて
入力フォームから入力した値のチェックを行うためにPostControllerのstoreメソッド内にバリデーションのコードを追加します。バリデーションはvalidateメソッドを用いて行い、テーブルの各列に対してルールを設定し、入力値のチェックを行います。ルールは各列に対して、複数設定することもできます。複数のルールを設定する場合は、区切り文字”|”を使って分けます。
validateメソッドの記述方法は下記となります。

validateメソッド
Laravel5.4などの古いバージョンを利用している場合に上記の記述では、Method validate does not exist.とエラーが表示されます。その場合は下記のように記述を書き換えてください。

postsテーブルのtitle列には、入力が必須となるルールrequiredと入力した行と重複の確認を行うルールuniqueを設定します。body列には、ルールrequiredのみ設定しています。
バリデーションに失敗した場合の流れ
validateメソッドを使用してバリデーションに失敗した場合はLaravelが内部でエラーの処理を行い自動で入力フォーム画面にリダイレクトされます。validateメソッドによるバリデーションにパスした場合はそのまま次の処理が実行されます。
JavaScriptからのリクエスト
ブラウザからアクセスした場合にバリデーションに失敗した場合はそのまま入力画面にリダイレクトが行われますが、fetch関数、axiosライブラリなどを利用してPOSTリクエストを送信した場合はリダイレクトの処理ではなくステータスコード422と一緒にバリデーションのエラーメッセージが戻されます。Laravelがリクエストの内容を見てどのようなResponseを行うのかを自動で判別してくれています。XHRリクエストの場合は戻されるエラーメッセージを利用してユーザに表示する処理を各自が実装する必要があります。
バリデーションルール
required, unique以外にもたくさんのバリデーションルールが事前に用意されています。Laravelのドキュメントを確認しながら必要なルールを見つけ適用していきます。 Laravelのバージョンアップとともにバリデーションの数も増えています。Laravel11のバリーデーションルールと5.8のバリデーションルールを掲載しているのでバリデーションルールが増えていることが確認できます。10から11でもルールが追加されています。


Concerns¥ValidatesAttributes.phpファイルを確認してください。(Laravel11で確認済)

ビューでのエラーメッセージの表示
バリデーションに失敗した場合にはユーザにフォームのどの入力項目でのエラーなのかメッセージで伝える必要があります。メッセージの表示設定はビューファイルで行います。
バリデーションに失敗するとブラウザとのSession情報にエラーメッセージが保存されます。先ほど説明した通りバリデーションに失敗すると入力フォーム画面にリダイレクトされるのでSessionに保存したエラーメッセージを使うことでユーザに入力内容にエラーがあったことを伝えることができます。
エラーメッセージを表示できるように入力フォームのビューであるcreate.blade.phpにメッセージを表示できる要素を追加します。
$errorsはバリデーションを実行するしないに関わらずビューからアクセスすることができる変数です。
$errors->any()は$errors変数の中にエラーメッセージが含まれているかどうかチェックを行うメソッドです。エラーメッセージがあればtrue、なければfalseを戻します。
$errors->all()は$errors変数からエラーを取得するメソッドで、戻り値にはバリデーションの中のチェックで発生したエラー情報が配列として保持しています。foreachを使用することで1つ1つのメッセージを取り出すことができます。
エラーメッセージの表示
バリデーションの動作確認を行うため入力フォームには何も入力せず”登録する”ボタンをクリックします。

titleにもbodyにも入力を行なっていなかったため、”field is required”のメッセージが表示されます。


ここまでの動作確認でバリデーションの設定方法とバリデーションに失敗した場合のエラーメッセージの表示方法を確認できました。
カスタマイズしたエラーメッセージの設定
初期設定ではエラーメッセージは英語で表示されます。メッセージをカスタマイズすることも可能です。以下のようにvalidateメソッドに表示したいメッセージの配列を追加します。
再度入力フォームに何も入力せず、登録ボタンを押すと追加したカスタマイズしたメッセージが表示されます。

@errorディレクティブ
errors変数を利用せず@errorディレクティブを利用することもできます。
エラーメッセージの日本語化
Laravel9からエラーファイルの保存場所が変更になります。Laravel9ではデフォルトのメッセージファイルは/lang/en/validation.phpファイルです。Laravel8まではresources/lang/en/validation.phpファイルです。validation.phpファイルが存在しない場合にはphp artisanコマンドを利用して作成することができます。
エラーメッセージをカスタマイズして日本語化する方法の確認を行いましたが、validation毎に個別に設定を行うのは非効率のため、一括で日本語化を行う方法を確認します。日本語化までの流れは下記の通りです。
Laravel9/10/11の場合
- config/app.phpファイルでロケールの変更
- langディレクトリにjaディレクトリ作成
- lang/en/validation.phpファイルをjaディレクトリに複製
- jaディレクトリ内のvalidation.phpファイルの更新
Laravel8以前までの場合
- config/app.phpファイルでロケールの変更
- resources/langディレクトリにjaディレクトリ作成
- resources/lang/en/validation.phpファイルをjaディレクトリに複製
- jaディレクトリ内のvalidation.phpファイルの更新
validationのエラーメッセージの一覧が登録されているファイルは、validation.phpに登録されています。
ロケールの設定
初期設定では、ロケールの設定が”en”になっているために”ja”に変更する必要があります。設定ファイルは、Laravelインストールディレクトリのconfig/app.phpで行います。Laravel10までは下記のように’en’を’ja’に変更します。
Laravel11で環境変数からlocalの値を設定します。
.envファイルを確認するとAPP_LOCALEの値が’en’に設定されているので’ja’に変更します。
validation.phpファイル複製
.envファイルまたはapp.phpファイルでロケールの設定完了後、langディレクトリにjaディレクトリを作成し、enディレクトリに保存されているvalidation.phpファイルをjaディレクトリの下に保存します。保存したvalidation.phpの中にあるrequiredを日本語に変更します。
下記はLarave8以前の場合です。

validationメッセージを日本語化
再度入力フォームに何も入力せず、ja/validation.phpファイルで日本語化したメッセージが表示されます。

requiredルールのみvalidation.phpファイルを利用して日本語化を行いましたが、他のルールのメッセージも英語から日本語に変更することですべてのエラーメッセージを日本語化することが可能になります。
validation.phpファイルをすべて自分で日本語化するのは大変なのでインターネットを検索するとvalidation.phpファイルを日本語化して公開している人がいるので参考にするのがいいです。
エラーメッセージの表示場所
エラーメッセージに取得に関するメソッド
入力した値毎にエラーメッセージを表示することが可能です。下記の方法で入力した項目(フィールド)のエラーメッセージを取り出すことが可能です。

firstメソッドでエラーメッセージを取得
firstメソッドでは、項目のvalidationでエラーになったルールのメッセージを1つしか取得することができません。すべてのルールのエラーメッセージを取得するためには、getメソッドを使用します。

getメソッドですべてのエラーを取得

各項目にエラーメッセージが入っているかどうかをチェックするhasメソッドもあります。

エラーメッセージを持っているかの確認
項目ごとのエラーメッセージ
hasメソッドとfirstメソッドを利用してエラーメッセージを表示します。hasメソッドでbodyフィールドにエラーがあるかチェックを行い、エラーがある場合のみfirstメソッドを利用してエラーを表示しています。
hasメソッドとgetメソッドを利用してエラーメッセージを表示します。hasメソッドでtitleフィールドにエラーがあるかチェックを行い、エラーがある場合にはgetメソッドですべてのエラーを配列で取得してforeach関数で展開してエラーメッセージを表示させています。
項目別にエラーメッセージを表示
これまでのエラーメッセージの設定を使って、エラーメッセージを表示場所を項目の下に表示させます。
再度入力フォームに何も入力せず、登録ボタンを押すと入力項目の下にエラーメッセージが表示されます。

エラーメッセージの表示場所を変更

フィールド名を変更する
項目別にエラーメッセージを表示することができましたが、titleは必須ですはテーブル作成時の列名(フィールド名)なのでこれを日本語のタイトルに変更したい場合もあるかと思います。
その場合は、validator.phpファイルのattributesに追加することで変更することができます。
titleをタイトルに変更すると以下のようにバリデーションエラーメッセージのtitleがタイトルに変わります。

カスタムバリデーション
Laravelにはデフォルトでさまざまなバリデーションが準備されていますが独自のバリデーションを作成したいということもあるかもしれません。その場合はカスタムバリデーションルールを利用することで対応することができます。カスタムバリデーションの作成方法についてはLaravel9から変更になっています。
ルールファイルの作成
入力フォームで住所を入力した場合の郵便番号のカスタムバリエーションを作成してみましょう。
app\Rulesフォルダの下にZipcode.phpファイルが作成されます。
作成したZipcodeファイルは下記のようにバリデーションで設定します。
Laravel9から
Laravel9からはZipcode.phpファイルにはvalidatedメソッドのみ入っています。
validateメソッドの引数$attribute, $valueと$failを受け取って$valueの値が条件を満たすかチェックを行います。条件を満たさない場合には$fail関数の引数にエラーメッセージに記述します。
バリデーション条件の設定
郵便番号の形式は3桁-4桁なので正規表現を利用してチェックを行います。
実際に入力した郵便番号でチェックすると163-8001ではバリデーションをパスしますが1638001や郵便の桁数の不足するものまた数字以外を入力すると”郵便番号の書式に誤りがあります”がエラーで戻されます。
メッセージの変更方法
属性の情報を表示したい場合は、:attributeを利用することでメッセージに属性名を表示させることができます。今回はzipcodeと表示されます。
エラー内容を記述したvalidation.phpファイルに記述された内容のメッセージを表示させたい場合は、translateメソッドを利用することができます。意図的にdateルールのメッセージを利用した場合は下記のように設定します。メッセージは”zipcode is not a valid date.”と表示されます。
zipcodeというメッセージをValication.phpファイルに追加することも可能です。validation.phpファイルを開いて下記を追加します。
zipcodeというメッセージをValication.phpファイルに追加することも可能です。validation.phpファイルを開いて下記を追加します。
ルールファイルのZipcode.phpファイルのメッセージ関数を以下のように変更します。
バリデーションに失敗するとメッセージで”エラー”が表示されます。
Laravel8まで
Laravel8まではZipcode.phpファイルの中身はpassesとmessageメソッドが入っています。passesメソッドは引数に$attributeと$valueを受け取って$valueの値が条件を満たすかチェックを行います。今回は$valueの値が郵便番号のフォーマットの条件を満たせばtrueを戻し、満たさなければfalseを戻します。もし、条件を持たさなかった場合は、messageメソッドに記述した内容がエラーメッセージとして戻されます。
バリデーション条件の設定
郵便番号の形式は3桁-4桁なので正規表現を利用してチェックを行います。
実際に入力した郵便番号でチェックすると163-8001ではバリデーションをパスしますが、1638001や郵便の桁数の不足するものまた数字以外を入力するとmessage関数のThe validation error messageがエラーで戻されます。
メッセージの変更方法
メッセージを変更したい場合は下記のように直接messageメソッドを変更することも可能です。
属性の情報を表示したい場合は、:attributeを利用することでメッセージに属性名を表示させることができます。今回はzipcodeと表示されます。
エラー内容を記述したvalidation.phpファイルに記述された内容のメッセージを表示させたい場合は、trans関数を利用することができます。意図的にdateルールのメッセージを利用した場合は下記のように設定します。
メッセージは”zipcode is not a valid date.”と表示されます。
zipcodeというメッセージをValication.phpファイルに追加することも可能です。validation.phpファイルを開いて下記を追加します。
ルールファイルのZipcode.phpファイルのメッセージ関数を以下のように変更します。
バリデーションに失敗するとメッセージで”エラー”が表示されます。
その他
validateメソッドの戻り値
validateメソッドを利用してバリデーションに失敗した場合には自動でリダイレクトが行われました。バリデーションに成功した場合にvalidateメソッドから戻される値を確認します。
titleに”Laravel Validate”, bodyに”バリデーションについての説明”を入力した場合にはバリデーションにパスしたフィールドと値を持つ配列が戻されます。
エラーメッセージを保存する場所を指定
バリデーションのエラーメッセージは$errors変数に保存されているので$errors->all()でメッセージを取得することができました。さらに細かくエラーの保存場所を指定したい場合にはvalidateWithBagを利用することができます。validateWithBagメソッドの第一引数に保存する場所の名前を指定します。ここでは”post”を設定しています。Laravelではエラーメッセージを保存している場所をMessageBagという呼びます。validateWithBagメソッドによってMessageBagの名前をpostに変更しています。
エラーを表示させるためにはBladeファイル側の更新も必要となります。
Bladeファイルでエラーのデバッグを行う
Bladeファイルで$errors変数の中にどのような値が保存されているのかdd関数を利用して確認します。
メッセージはViewErrorBagの中に入っていることがわかります。さらにMessageBagの名前が”default”であることもわかります。

ViewErrorBagはvendor/larave/framework/src/illuminate/Support/にあるViewErrorBag.phpファイルに対応するのでViewErrorBag.phpファイルを確認することでドキュメントに記載されていないメソッドなどを確認することができます。例えばcountメソッドを利用することでdefaultバッグに保存されているメッセージの数を表示することができます。

$errors-count()の値は最初はエラーがないため0と表示されていますがエラーが発生するとtitleとbodyの2つのメッセージを持っているので2と表示されます。
validateWithBagメソッドを利用した場合にはどのような変化が起こるのか確認します。
Bladeファイルではdd関数を利用してデバッグします。
一見先程と同じ内容にみえますが”default”が”post”になっていることがわかります。validateWithBagによってMessageBagの名前を”default”から”post”に変更していることがわかります。

sessionヘルパー関数を利用してエラーメッセージを取得
エラーの情報はSessionに保存されるという話を本文書の冒頭で説明しましたがsessionヘルパー関数を利用してバリデーションのエラーメッセージを取得することができます。

エラーをSessionファイルで確認
バリデーションのエラーはSessionに保存されているのでSessionファイルにもエラーメッセージが保存されています。storage/framework/sessionsに保存されているSessionファイルを開いてください。ファイル名はSession毎に設定されているため環境により異なります。
アプリケーションを構築する際にどのルールを利用するか個別に吟味する必要がありますが本文書を読み終えたのでLaravelのバリデーションの最初の一歩を踏み出すことができます。Laravelのドキュメンテーションを見ると今回の説明はLaravelバリデーションを一部にすぎません。本文書をベースにバリデーションの理解をさらに深めていってください。