Laravel 11.x で実践するフラッシュメッセージとバリデーション ～ 基礎から応用まで完全ガイド


Laravel はシンプルかつ強力なバリデーション機能と、ユーザーへのフィードバック用にフラッシュメッセージ（セッションを利用した一時的なメッセージ）の機能を備えています。  
この記事では、これらの基本的な使い方から、カスタムエラーメッセージや独自ルールの実装、さらに応用例までを網羅的に解説します。

---

## 1. はじめに

Web アプリケーション開発では、  
- ユーザーに「操作完了」や「エラー発生」などの情報を一時的に表示する **フラッシュメッセージ**  
- ユーザー入力に対して自動的に検証を行い、エラーの場合はフィードバックする **バリデーション**  

が非常に重要です。  
Laravel ではこれらがとても簡単に実装でき、基本機能に加え柔軟なカスタマイズも可能です。

---

## 2. フラッシュメッセージ

### 2-1. フラッシュメッセージの基本

フラッシュメッセージは、セッションに一時的なメッセージを保存して、次回のリクエスト時に表示する仕組みです。  
例えば、ユーザー登録後に「登録に成功しました」といったメッセージを表示する場合に利用します。

#### コントローラでの設定例

```php
// app/Http/Controllers/UserController.php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\User;

class UserController extends Controller
{
    public function store(Request $request)
    {
        // バリデーション処理は後述のバリデーションセクションを参照
        $validated = $request->validate([
            'name'     => 'required|string|max:255',
            'email'    => 'required|email|unique:users,email',
            'password' => 'required|min:6',
        ]);

        // ユーザー作成（例としてシンプルに）
        User::create([
            'name'     => $validated['name'],
            'email'    => $validated['email'],
            'password' => bcrypt($validated['password']),
        ]);

        // フラッシュメッセージを設定してリダイレクト
        return redirect()->route('users.index')
                         ->with('status', 'ユーザー登録に成功しました！');
    }
}
```

#### Blade テンプレートでの表示例

```blade
<!-- resources/views/layouts/app.blade.php の一部 -->
@if (session('status'))
    <div class="alert alert-success">
        {{ session('status') }}
    </div>
@endif

{{-- ここにコンテンツ --}}
@yield('content')
```

### 2-2. 応用：複数のフラッシュメッセージ

複数の種類のメッセージ（成功、警告、エラーなど）を表示したい場合は、キーを分けて設定できます。

#### コントローラ側

```php
return redirect()->route('dashboard')
                 ->with([
                     'status_success' => '操作は成功しました！',
                     'status_warning' => 'ただし、注意が必要な点があります。',
                 ]);
```

#### Blade 側

```blade
@if (session('status_success'))
    <div class="alert alert-success">
        {{ session('status_success') }}
    </div>
@endif

@if (session('status_warning'))
    <div class="alert alert-warning">
        {{ session('status_warning') }}
    </div>
@endif
```

### 2-3. with() と withErrors() の違い

Laravel では、ユーザーへのフィードバックメッセージを設定する際に、**with()** と **withErrors()** の 2 つのメソッドが用意されています。それぞれの用途は以下の通りです。

- **with()**  
  一般的なフラッシュメッセージ（成功メッセージや警告、単一のエラーメッセージなど）を設定するために使用します。  
  例えば、上記のユーザー登録成功時の例では、  
  ```php
  return redirect()->route('users.index')
                   ->with('status', 'ユーザー登録に成功しました！');
  ```  
  のように、指定したキー（ここでは `status`）でセッションに一時的なメッセージを保存します。Blade テンプレートでは `session('status')` を使ってこのメッセージを表示できます。

- **withErrors()**  
  主にバリデーションエラーなど、複数のエラーメッセージを扱う場合に使用されます。  
  例えば、認証失敗時に入力エラーを返す場合、  
  ```php
  return back()->withErrors([
      'email' => 'メールアドレスまたはパスワードが正しくありません。',
  ]);
  ```  
  のように記述します。`withErrors()` で設定されたエラーメッセージは、ビューに自動的に `$errors` オブジェクトとしてバインドされ、Blade テンプレートでは以下のように利用します。

  ```blade
  @if ($errors->has('email'))
      <div class="alert alert-danger">
          {{ $errors->first('email') }}
      </div>
  @endif
  ```

**まとめると：**

- **with()** → セッションフラッシュデータとしてメッセージを保存し、`session('key')` で取得する。  
- **withErrors()** → バリデーションエラーなど複数のエラーメッセージを `$errors` オブジェクトに格納し、`$errors->first('key')` などで表示する。

---

## 3. バリデーション

Laravel のバリデーションは、コントローラ内で簡単に実装できるほか、フォームリクエストクラスを利用することで、さらにコードを整理できます。

### 3-1. コントローラ内でのバリデーション

#### シンプルなバリデーション例

```php
// app/Http/Controllers/LoginController.php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;

class LoginController extends Controller
{
    public function login(Request $request)
    {
        // バリデーション実行
        $credentials = $request->validate([
            'email'    => 'required|email',
            'password' => 'required',
        ]);

        // 認証試行
        if (Auth::attempt($credentials)) {
            return redirect()->intended('dashboard');
        }

        // 認証失敗時にエラーメッセージをバリデーションエラーとして設定してリダイレクト
        return back()->withErrors([
            'email' => 'メールアドレスまたはパスワードが正しくありません。',
        ])->onlyInput('email');
    }
}
```

### 3-2. フォームリクエストを利用したバリデーション

フォームリクエストを利用すると、バリデーションロジックを専用クラスに切り出すことができ、コントローラがスッキリします。

#### フォームリクエストの作成

```bash
php artisan make:request LoginRequest
```

#### LoginRequest の例

```php
// app/Http/Requests/LoginRequest.php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class LoginRequest extends FormRequest
{
    public function authorize()
    {
        // 認可ロジック。通常、ログイン処理は誰でも利用できるので true
        return true;
    }

    public function rules()
    {
        return [
            'email'    => 'required|email',
            'password' => 'required',
        ];
    }

    public function messages()
    {
        return [
            'email.required'    => 'メールアドレスを入力してください。',
            'email.email'       => '正しいメールアドレスを入力してください。',
            'password.required' => 'パスワードを入力してください。',
        ];
    }
}
```

#### コントローラでの利用例

```php
// app/Http/Controllers/LoginController.php

namespace App\Http\Controllers;

use App\Http\Requests\LoginRequest;
use Illuminate\Support\Facades\Auth;

class LoginController extends Controller
{
    public function login(LoginRequest $request)
    {
        // フォームリクエストでバリデーション済みのデータを取得
        $credentials = $request->validated();

        if (Auth::attempt($credentials)) {
            return redirect()->intended('dashboard');
        }

        return back()->withErrors([
            'email' => 'メールアドレスまたはパスワードが正しくありません。',
        ])->onlyInput('email');
    }
}
```

### 3-3. 応用：カスタムバリデーションルール

Laravel では、カスタムバリデーションルールを作成して柔軟な検証が可能です。

#### カスタムルールの作成

```bash
php artisan make:rule Uppercase
```

#### Uppercase ルールの例

```php
// app/Rules/Uppercase.php

namespace App\Rules;

use Illuminate\Contracts\Validation\Rule;

class Uppercase implements Rule
{
    public function passes($attribute, $value)
    {
        // 文字列がすべて大文字かどうかをチェック
        return strtoupper($value) === $value;
    }

    public function message()
    {
        return 'The :attribute must be uppercase.';
    }
}
```

#### バリデーションでの利用例

```php
use App\Rules\Uppercase;

$request->validate([
    'code' => ['required', new Uppercase],
]);
```

---

## 4. エラーメッセージの表示（バリデーションエラー）

バリデーションエラーは自動的にセッションに保存され、Blade テンプレートから以下のように簡単に表示できます。

```blade
@if ($errors->any())
    <div class="alert alert-danger">
        <ul>
            @foreach ($errors->all() as $error)
                <li>{{ $error }}</li>
            @endforeach
        </ul>
    </div>
@endif
```

---

## 5. まとめ

- **フラッシュメッセージ:**  
  コントローラで `with()` や `session()->flash()` を利用して設定し、Blade テンプレートで `session('key')` として表示することで、ユーザーへの一時的なフィードバックを実現できる。

- **バリデーション:**  
  コントローラ内で直接 `$request->validate()` を利用する方法や、フォームリクエストクラスを利用してバリデーションロジックを切り出す方法があり、さらにカスタムルールを追加することで柔軟な入力チェックが可能になる。

- **with() と withErrors() の使い分け:**  
  - `with()` は一般的なフラッシュメッセージをセッションに一時保存し、ビューでは `session('key')` を利用して取得する。  
  - `withErrors()` はバリデーションエラーなど、複数のエラーメッセージを `$errors` オブジェクトに格納し、ビューでは `$errors->first('key')` や `$errors->all()` で表示する。

- **応用例:**  
  複数のフラッシュメッセージ、カスタムエラーメッセージ、カスタムバリデーションルールなどを組み合わせることで、よりユーザーフレンドリーで堅牢なアプリケーションを構築できる。

これらのテクニックを活用し、Laravel 11.x のフラッシュメッセージとバリデーション機能を効果的に使いこなしてください！

---

## 参考リンク

- [Laravel 11 公式ドキュメント - Validation](https://laravel.com/docs/11.x/validation)
- [Laravel 11 公式ドキュメント - Form Requests](https://laravel.com/docs/11.x/requests)
- [Laravel 11 公式ドキュメント - Session](https://laravel.com/docs/11.x/session)
- [Laravel 11 公式ドキュメント - Error Messages](https://laravel.com/docs/11.x/validation#custom-error-messages)

---

以上、Laravel 11.x におけるフラッシュメッセージとバリデーションの基礎から応用までの完全ガイドでした。ご質問やコメントがあれば、お気軽にどうぞ！