【FormRequest編】Laravelのバリデーションエラーを日本語化する方法

Laravel
※当サイトはアフィリエイト広告を掲載しています。

Laravelのバリデーションは、デフォルトでは英語のエラーメッセージが表示されます。これを日本語表示させたい場合の選択肢の一つが、FormRequestを継承した子クラス内での設定です。

日本語表示させる場合、以下の選択肢があります。

  1. FormRequestクラスの子クラスで設定する
  2. 言語ファイルで設定する

本ページでは1のFormRequestクラスを使った日本語化について詳しく解説します。ピンポイントでさっと適用できる点で、2と比べメリットがあります。

2の言語ファイルで設定する方法はこちらで解説していますのでご参照ください。。

米言語ファイル(/lang/js/validate.php)での日本語化する方法は、別途記事にしたいと思います。

本ページでは、Laravel10系を利用しています。

本ページでやること

概要

  • FormRequestを継承したInquiryRequestクラスを作成
  • バリデーションルールは名前とメールアドレス
  • それらについて日本語のエラーメッセージを表示する

完成コード

最初に、本ページで最終的に実装する最終形をここに挙げます。ある程度Laravelに慣れている方は、これを読むだけで解決するかもしれません。

そうでない方も、俯瞰して見ていただくため、流し読みしてから読み進めていただければと思います。

<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class InquiryRequest extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     */
    public function authorize(): bool
    {
        return true;
    }

    /**
     * バリデーションルールを定義
     *
     * @return array
     */
    public function rules(): array
    {
        return [
          'name' => ['required', 'max:10'],
          'email' => ['required', 'email'],
        ];
    }

    /**
     * バリデーションエラーメッセージを定義
     *
     * @return array
     */
    public function messages(): array
    {
        return [
          'name.required'  => ':attributeは必須項目です。',
          'name.max'       => ':attributeは最大:max文字以内で入力してください。',
          'email.required' => ':attributeは必須項目です。',
          'email.email'    => ':attributeを正しく入力してください。',
        ];
    }

    /**
     * カスタム属性名を定義
     *
     * @return array
     */
    public function attributes(): array
    {
        return [
            'name' => 'お名前',
            'email' => 'Email',
        ];
    }
}

前準備

ファイルを用意する

まず最初に、FormRequestを継承した子クラスを定義するファイルを作成します。すでに済んでいる方は飛ばしてください。

本ページではInquiryRequestという名称のクラスでファイルを作成したいので、以下のコマンドを打ちます。ご希望のファイル名に直して打ち込んでください。

php artisan make:request InquiryRequest

これにより、以下のようにFormRequestクラスを継承したファイルが生成されます。

app\Http\Requests\InquiryRequest.php

ファイル指定を、Contact\InquiryRequest のバックスラッシュ(Windowsは半角の¥)で区切れば、Contactディレクトリの下層に作る……などということも可能です。

authorizeをtrueに

ファイルを生成した状態だとバリデーション自体ができません。authorizeメソッドの戻り値をtrueに変更しておきましょう。

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

ちなみにこれがfalseだと、このクラスを利用する許可(authorize)が無いことを意味します。Laravelが親切でやってくれている機能ですが、無条件でtrueを返す場合も多いです。

もちろん、実際のWebアプリケーションでは、適切な許可がある場合のみtrueを返すようにコードを書いてください。

Lara
Lara

初心者の頃は忘れがちで、私も「なぜバリデーションできない!?」とはまりました。

バリデーションルールを考える

そもそものバリデーションルール自体が無いと、エラーメッセージを作ることができません。どのようなルールにするか考えてみてください。

本ページでは以下をルールに設定します。説明用なのでシンプルにしました。

    public function rules(): array
    {
        return [
          'name' => ['required', 'max:10'],
          'email' => ['required', 'email'],
        ];
    }

ルール指定がまだよくわからない方は、以下の初心者用の記事もご参照ください。

日本語のエラーメッセージを設定

messagesメソッドを作成

以下のように、親クラスで定義されているmessagesメソッドをオーバライドします。

    public function messages(): array
    {
        // 配列を返す必要あり
    }

この名称の通り、エラーメッセージを返すメソッドです。配列で指定する必要があります。

バリデーションに対応したエラーメッセージを定義

messagesメソッド内に、自分で作成したバリデーションルール毎のエラーメッセージを定義していきます。

具体的には、

項目名.バリデーションルール

のように、ドットで連結したものにエラーメッセージが対応します。

    public function messages(): array
    {
        return [
          'name.required'  => 'お名前は必須項目です。',
          'name.max'       => 'お名前は最大10文字以内で入力してください。',
          'email.required' => 'Emailは必須項目です。',
          'email.email'    => 'Emailを正しく入力してください。',
        ];
    }

本例では、以下となります。

  • name.required
  • name.max(ルールはmax:10ですが、パラメータ部分は入れません)
  • email.required
  • email.email

バリデーションルール毎に細かくエラーを設定できるということですね。

例えば、名前を入力していない場合に以下のエラーが利用されます。

'name.required'  => 'お名前は必須項目です。',

これでエラーメッセージの日本語化は完成です。

さらに便利な使い方

これだけでも充分便利!と思う方は多いと思います。実際、こういった使い方にとどめられているLaravelアプリケーションも多いでしょう。

しかしここでは、さらにこんな使い方もできるよ、ということをご紹介したいと思います。

項目名も変数で定義したい

お名前は○○してください……というのを繰り返すのは、なんだかクールではないと感じることもあるかもしれません。今回で言えば以下の部分です。

 'name.required'  => 'お名前は必須項目です。',
 'name.max'       => 'お名前は最大10文字以内で入力してください。',

2つだったらまだしも、4つも5つも似たメッセージがあれば、何かアイデアが無いか!?と思う所でしょう。

実はこちらは、Laravelの:attributeという機能で対処することができます。まず、バリデーションルールに使用しているnameとemailに、日本語の名前を定義してあげます。

具体的には以下のように、親クラスのattributes()をオーバライド(上書き)して利用します。

    public function attributes()
    {
        return [
            'name' => 'お名前',
            'email' => 'Email',
        ];
    }

これでnameはお名前、emailがEmailだとLaravelで定義することができました。

次に、以下の様にエラーの項目名を:attributeとします。

    public function messages(): array
    {
        return [
          'name.required'  => ':attributeは必須項目です。',
          'name.max'       => ':attributeは最大10文字以内で入力してください。',
          'email.required' => ':attributeは必須項目です。',
          'email.email'    => ':attributeを正しく入力してください。',
        ];
    }

正しく指定できれば、これだけで:attribute部分が日本語に置き換わります。:attributeがプレースホルダーのように機能するわけですね。

場合によっては、よりスッキリとしたコードになるかもしれません。

バリデーション項目が多いとすっきりしますが、そのまま書いても楽で分かりやすい場合もあります。必ず:attributeを使わねばいけないわけではありません。

ルールの一部も変数で定義したい

先ほどのコードで奇なる箇所が、まだ1箇所あります。それは以下です。

'name.max' => ':attributeは最大10文字以内で入力してください。',

max:10になっているので正しいと言えば正しいです。しかし、バリデーションルールが20に変わった時にはこちらも直さなければなりません。

もし修正を忘れると、問題になる可能性もあります。そのためこういった仕様はあまり良いとされません。

実はLaravelには、この対処法も備わっています。まず、該当箇所を以下のように:maxとします。

'name.max' => ':attributeは最大:max文字以内で入力してください。',

たったこれだけで、これまでと同様に動作します。

以下の通り、ルールでmax:10と定義してあることにより、maxというルール名にコロンを足した:maxを、Laravel側でプレースホルダーにしてくれているのです。

    public function rules(): array
    {
        return [
          'name' => ['required', 'max:10'],
          'email' => ['required', 'email'],
        ];
    }

自動的に、良い感じにしてくれるのはLaravelの良いところ。使っていて楽しくなりますね。

maxの他にも同様に使えるので、このあたりは別記事にまとめたいと思います。

laravelに限らず、コロンを付けた文字列はプレースホルダーとして使われることが多いです。DBを操作するPDOのプレースホルダーもそうですので、PHPerにはなじみやすいです。

まとめ

以上、FormRequestクラスを用いた日本語化について解説しました。

クラス内で完結できるので、覚えれば簡単に日本語化できるはずです。ただ、それぞれのFormRequestの子クラスで行うのは重複があると不便です。

そういった場合にはLaravelの言語ファイルを修正して対応する方法もあります。

コメント

タイトルとURLをコピーしました