Laravelのバリデーションエラーを日本語化する

この記事は、コントローラー、ルート、ビュー、クラスの設定が済んでいることを前提としています。
その設定ができてない方は、ページ下のサンプルコードも参考にしてみてください。

日本語表示させるにはどうすればよいか
---------------------------------------

Laravelのバリデーションは、デフォルトでは英語のエラーメッセージが表示されます。以下の様な感じです。





![スクリーンショット 2024-04-08 163837.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3712387/ffd174ba-4378-53cb-b27a-1840b8524f8e.png)



日本語表示させる場合は、言語ファイルを設定する方法があります。
言語ファイルを設定する前に2点確認してください。


### ①ロケールが日本になっているか
ロケール＝アプリケーションのデフォルトの言語が、日本語になっていることを確認します。

具体的には、**config/app.php**の中にあるlocaleが’ja’になっていることを確認してください。
```config.app.php
    'locale' => env('APP_LOCALE', 'ja'),

```
また、**.env**のlocalも確認して’ja’に変更しておきましょう。
```.env
APP_LOCALE=ja
```

### ②laディレクトリがあるか
言語ファイルがすでにあれば、新たに作成する必要はありません。ですので、まずは言語ファイルを探してみましょう。

Laravel9より前のバージョンの場合、もしくはLaravel9以前からアップデートしてLaravel9～11にされている方は、resources/lang/内にディレクトリが無いか確認してみてください。

もしすでにある場合、あなたの環境ではそれが正式な言語ファイルの設置場所です。本記事のlang/はresources/lang/と読みかえてください。

最初からLaravel9～の場合は、langディレクトリがあるかをご確認ください。
ここまで確認ができたら言語ファイルを作成していきましょう！

 言語ファイルの作成
 ---------------------------------------
今回、バリデーション関連の言語ファイルである、lang/ja/validation.phpという設定ファイルを作るのが目的です。すでにあれば作成しなくてOKですので、以下をご確認ください。

:::note infolang/ja/validation.phpがある→作成しなくてOK
lang/en/validation.phpがある→ enディレクトリを複製してjaにし、その中のvalidation.phpを編集します。
lang/が無い→次の方法で用意します。
lang/が無い場合のみ、以下のコマンドを打ってください。
:::
```
php artisan lang:publish
```

すると、**lang/en**というディレクトリが出来ていると思います。続いてlang内のenを複製し、jaと名前を変えます。

これで結果的に、**lang/ja/validation.php**というファイルが出来ているはずです。

このファイルを編集していきましょう。

ファイル内容を理解する
---------------------------------------
実際に修正する前に、**lang/ja/validation.php**ファイルがどういう構造なのかを眺めておきましょう。

私の環境では、以下の様になっていました。

```lang/ja/validation.php
<?php

return [

    /*
    |--------------------------------------------------------------------------
    | Validation Language Lines
    |--------------------------------------------------------------------------
    |
    | The following language lines contain the default error messages used by
    | the validator class. Some of these rules have multiple versions such
    | as the size rules. Feel free to tweak each of these messages here.
    |
    */

    'accepted' => 'The :attribute field must be accepted.',
    'accepted_if' => 'The :attribute field must be accepted when :other is :value.',
    'active_url' => 'The :attribute field must be a valid URL.',
    'after' => 'The :attribute field must be a date after :date.',
    'after_or_equal' => 'The :attribute field must be a date after or equal to :date.',
    'alpha' => 'The :attribute field must only contain letters.',
    'alpha_dash' => 'The :attribute field must only contain letters, numbers, dashes, and underscores.',
    'alpha_num' => 'The :attribute field must only contain letters and numbers.',
    'array' => 'The :attribute field must be an array.',
    'ascii' => 'The :attribute field must only contain single-byte alphanumeric characters and symbols.',
    'before' => 'The :attribute field must be a date before :date.',
    'before_or_equal' => 'The :attribute field must be a date before or equal to :date.',
    'between' => [
        'array' => 'The :attribute field must have between :min and :max items.',
        'file' => 'The :attribute field must be between :min and :max kilobytes.',
        'numeric' => 'The :attribute field must be between :min and :max.',
        'string' => 'The :attribute field must be between :min and :max characters.',
    ],
// ～省略～
    'attributes' => [],
];
```
### リクエストクラスの設定
設定できている方は、とばしてください！
バリデーションするためには、FormRequestクラスも必要です。
以下のコマンドでCreateReqest.phpというファイルを作成することにします。(ファイル名は)
```
php artisan make:request CreateRequest
```
CreateRequest.phpファイルが作成されます。今回は画像にあったような名前の入力フォーム必須チェックをするという想定で、以下のように編集します。
```CreateRequest.php
<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class CreateRequest extends FormRequest
{
    public function authorize(): bool
    {
        return true;
    }

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


```
:::note info
\<input type="text" name='name'>の'name'。フォームの値のバリデーションルールを定義している。
requiredは必須チェックなので入力されていないとエラーになる。
:::
### 項目名の設定

```lang/ja/validation.php
'attributes' => [
// ここに配列で定義する
        'name'  => '名前',
],
```
 attributesは、項目名の日本語化で使用します。
**attributes**では、お名前、メールアドレス、電話番号などの項目名を日本語化するのに使います。なお、’attributes’はファイルの最後の方にあります。
例えば、上記のように項目名を日本語に設定できます。



### エラーメッセージの設定
```lang/ja/validation.php
'required' => 'The :attribute field is required.',
```
:::note info 
**attributes**以外ではルールに対応するエラーメッセージの日本語化で使用します。
例えば以下はバリデーションルールが**required**にて、エラーが発生したときの文言です。
:::
例えば、このようにして日本語に変更できます。
```lang/ja/validation.php
'required' => ':attributeが入力されていません。',
```
:::note info
:attribute部分は置き換わるので、今のところはそのまま残してください。

コロンがついた文字列はプレースホルダーと言い、Laravelが他の文字に置き換える用途に使われます。コロンがついた英単語は全てそのまま残してください。
:::

###### これで、以下の様に無事日本語化できました！
![スクリーンショット 2024-04-08 164342.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3712387/86039cc7-4a08-65bd-4d06-18ab82173aa4.png)

まとめ
------------------------------------------------------
以上、言語ファイルを編集して、Laravelのバリデーションエラー時のメッセージを日本語化しました。

**1\.ロケールを確認する**。
**2\.langフォルダを確認する。**
**3\.言語フォルダを作成する**
**4\.項目名を設定する。**

今回は日本語化するという目的に焦点を当てているため必要最低限の説明となっています。
これらは、コントローラー、ルート、ビュー、クラスの設定が済んでいることを前提としています。
その設定ができてない方は、以下のサンプルコードも参考にしてみてください。

<details><summary>index.blade.php</summary>


```php
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>バリデーションテスト</title>
</head>
<body>
    <h1>バリデーションテスト</h1>
    <div>
        <br>
        <form action="{{ route('tweet.create') }}" method="post">
            @csrf
            <label for="tweet-content">名前</label>
            <input name="name" id="tweet-content" type='text' placeholder="名前を入力"><br>
            <br>
            @error('name')
                <p style="color:red;">{{ $message }}</p>
            @enderror
            <button type="submit">送信</button>
        </form>
    </div>
</body>
</html>

```
</details>

<details><summary>web.php</summary>


```php
<?php

use Illuminate\Support\Facades\Route;

Route::post('sample/create', App\Http\Controllers\Tweet\CreateController::class)->name('sample.create');
```
</details>

<details><summary>CreateController.php</summary>


```php
<?php

namespace App\Http\Controllers;

use App\Http\Controllers\Controller;
use App\Http\Requests\CreateRequest;
use Illuminate\Http\Request;

class CreateController extends Controller
{
    public function __invoke(CreateRequest $request)
    {
        //
    }
}

```
</details>

<details><summary>CreateRequest.php</summary>


```php
<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class CreateRequest extends FormRequest
{
    public function authorize(): bool
    {
        return true;
    }
    
    public function rules(): array
    {
        return [
          'name' => 'required'
        ];
    }
}
```
</details>