3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Laravel】バリデーションの基本と切り分けについて

3
Last updated at Posted at 2026-08-20

Laravelを勉強していると必ず登場する、
Validation(バリデーション)

今回はバリデーションについて、

  • そもそも何なのか
  • なぜ必要なのか
  • Controllerに直接書く方法
  • Form Requestを使う方法
  • Form Requestの便利な機能

まで、RPGの世界に例えながら整理してみます。

バリデーションを一言で

門番です。

もう少し正確に言うと、
アプリケーションに入ってくるデータが、
決められたルールを守っているか確認する仕組みです。

バリデーションの恩恵

RPGの世界にあるギルドで考えてみます。

👦 Request(村人)

「畑の作物を食い荒らす魔物がいて困っているんです!」

「ギルドに討伐依頼を出しに来ました!」

村人は依頼書を書きます。

{
    "enemy": "",
    "place": "むら"
}

そしてギルドへ。

🚶‍♂️...

👩‍🦰 Validation(ギルド受付)

「ご依頼ありがとうございます!」

「まずは依頼内容を確認しますね!」

依頼書を確認すると……

enemy → 空っぽ
place → むら

受付:

「敵の名前が書かれていませんね……」
「これでは勇者に依頼を出せないので、enemyを書いてからもう一度お願いします!」

なぜ受付の人はこれを判断できたのでしょうか?
例えば、ギルド側でこんなルールが決められていたとします。

enemy→ 必須
place→ 必須

もしValidationをせずに、そのまま依頼ボード(DB)へ保存すると、

依頼名:ゴブリン討伐

敵:
場所:むら

のような不完全な依頼が登録される可能性があります。

勇者:

「敵……誰やねん。」

逆に、

敵:ゴブリン
場所:

なら、

勇者:「どこ行ったらええねん。」
となります。

村人の状況を考えると
少し厳しいようですが、結果的には

  • ユーザー
  • 開発者
  • DB
  • アプリケーション

みんなを守ってくれています。

LaravelでValidationを書く方法

Laravelでは、大きく分けて2つの書き方があります。

  1. Controllerに直接Validationを書く
  2. Form RequestにValidationを分離する
方法 メリット デメリット
Controller内Validation すぐ書ける・小さい処理なら分かりやすい Controllerが長くなりやすい
Form Request Validationを分離できる・Controllerがスッキリする ファイルが増える・小さい処理では少し大げさ

RPGで考えると

Controller内Validation

勇者:

「入場チェックもする!」
「戦闘もする!」
「姫様も救う!」
「王様も助ける!」
「宝箱も開ける!」

勇者:「仕事が多すぎるーー」
Controllerも同じで、色々な処理を書きすぎると役割が増えすぎます。

Form Request

そこで、

👩‍🦰 門番:
「入力チェックは私が担当します!」

⚔️ 勇者:
「じゃあ俺は戦闘に集中する!」
という役割分担をします。

Request
   ↓
Form Request
「入力チェックは任せろ!」
   ↓
Controller
「本来の処理をやるぞ!」

これがForm Requestのイメージです。

いろんな条件で制限をかけられる

こういった条件でデータを制限していきます。
一つだけ使うことも、組み合わせて使うこともできます。

Validation 意味
required 必須
nullable nullを許可
string 文字列
integer 整数
numeric 数値
boolean 真偽値
email メールアドレス形式
min:3 最小値・最小文字数など
max:255 最大値・最大文字数など
confirmed 確認用フィールドと一致
unique:quests,title DB上で重複していないか確認
exists:users,id DBに値が存在するか確認

Controllerに直接Validationを書く

例えば、

title
→ 必須
→ 文字列
→ 最大255文字

level
→ 必須
→ 整数
→ 1以上
というルールを設定するとして

public function store(Request $request)
{
    $validated = $request->validate([
        'title' => 'required|string|max:255',
        'level' => 'required|integer|min:1',
    ]);

    Quest::create($validated);
}

$request->validate() の中にバリデーションを書く

$request->validate([
    'title' => 'required|string|max:255',
    'level' => 'required|integer|min:1',
]);

例えば、

{
    "title": "ドラゴン討伐",
    "level": 20
}

なら通過します。

しかし、

{
    "title": "",
    "level": 0
}

なら、

title
→ required違反

level
→ min:1違反

となりValidationエラーになります。

Form Requestとは

Form Requestは、

ValidationやRequestに関係する処理を専用クラスへ切り出す仕組み
です。

基本的には、

app/
└── Http/
    └── Requests/

に作成します。

Form Requestを作成する

Artisanコマンドを使います。

php artisan make:request StoreQuestRequest

すると、

app/
└── Http/
    └── Requests/
        └── StoreQuestRequest.php

が作成されます。

Form Requestを書く

<?php

// app/Http/Requestsに属していることを表す
namespace App\Http\Requests;

// Laravel標準のFormRequestクラスを読み込む
use Illuminate\Foundation\Http\FormRequest;

// Quest作成用のForm Request
class StoreQuestRequest extends FormRequest
{
    // このRequestを実行していいユーザーか判定
    public function authorize(): bool
    {
        // trueなら許可
        // falseなら拒否
        return true;
    }

    // Validationルール
    public function rules(): array
    {
        return [
            // 必須・文字列・最大255文字
            'title' => 'required|string|max:255',

            // 必須・整数・1以上
            'level' => 'required|integer|min:1',
        ];
    }
}

Controller側

作成したForm RequestをControllerで使います。

use App\Http\Requests\StoreQuestRequest;

public function store(StoreQuestRequest $request)
{
    // Validationを通過したデータだけ取得してDBへ保存
    Quest::create(
        $request->validated()
    );
}

ここで重要なのが、

StoreQuestRequest $request

Laravelは、

Controller
「StoreQuestRequestが必要です」
        ↓
Laravel
「了解」
        ↓
StoreQuestRequestを用意
        ↓
Validation実行
        ↓
成功したらControllerへ

という流れで処理してくれます。

$request->validated() とは?

Form Requestでは、

$request->validated()

をよく使います。

これは、
Validation対象になっていて、Validationを通過したデータを取得する

ためのメソッドです。

例えばRequestが、

{
    "title": "魔王討伐",
    "level": 50,
    "cheat_code": "999999"
}

だったとして、

Form Requestが、

public function rules(): array
{
    return [
        'title' => 'required|string',
        'level' => 'required|integer',
    ];
}

なら、

$request->validated();

で扱う中心になるのは、

[
    'title' => '魔王討伐',
    'level' => 50,
]

です。

cheat_codeはValidationルールの対象にしていません。

そのため、DB保存などでは、

$request->all()を何でもそのまま渡すより、
$request->validated()
を利用する方が意図が明確になります。

Form Requestの便利機能一覧

Form RequestにはValidation以外にも便利なメソッドがあります。

メソッド 何をする? ざっくり例
authorize() Requestを実行していいか確認 管理者だけ許可
rules() Validationルールを定義 `required
messages() エラー文を変更 「クエスト名は必須です」
attributes() 項目名を分かりやすくする titleクエスト名
prepareForValidation() Validation前に値を整える trim()
passedValidation() Validation成功後に処理 値の追加加工
withValidator() 複雑な追加Validation 2項目を比較

authorize()

このRequestを実行してよいか確認します。

public function authorize(): bool
{
    return true;
}

trueなら許可。falseなら拒否されます。

public function authorize(): bool
{
    return auth()->user()->level >= 100;
}

とすれば、
level 100以上
→ 許可
level 100未満
→ 拒否
という使い方もできます。

rules()

Validationの中心です。

public function rules(): array
{
    return [
        'title' => 'required|string|max:255',
        'level' => 'required|integer|min:1',
    ];
}

RPGでいうなら、ギルドの受付条件一覧です。

messages()

Validationエラーのメッセージを変更できます。

public function messages(): array
{
    return [
        'title.required' => 'クエスト名を入力してください。',
        'level.min' => '推奨レベルは1以上にしてください。',
    ];
}

例として
title.required

title

required違反に対応しています。

attributes()

項目名を人間向けの名前に変更できます。

public function attributes(): array
{
    return [
        'title' => 'クエスト名',
        'level' => '推奨レベル',
    ];
}

つまり、titleというプログラム上の名前を、
クエスト名としてエラー表示などに利用できます。

prepareForValidation()

Validationする前に入力値を整えることができます。

例えば、

{
    "title": "   魔王討伐   "
}

のように余計な空白が入っているとします。

protected function prepareForValidation(): void
{
    $this->merge([
        'title' => trim($this->title),
    ]);
}

これによって、

"   魔王討伐   "
        ↓
"魔王討伐"

にしてからValidationできます。

RPGでいうと、ギルド受付の前に依頼書を整える係です。

passedValidation()

Validation成功後に処理を追加できます。

protected function passedValidation(): void
{
    $this->merge([
        'title' => '【QUEST】' . $this->title,
    ]);
}

例えば、魔王討伐【QUEST】魔王討伐になります。

withValidator()

rules()だけでは書きづらい追加チェックをしたい場合に使えます。

例えば、

開始レベル:20
終了レベル:10

という入力が来たとします。

終了レベルが開始レベルより小さいので、おかしいですね。

public function withValidator($validator): void
{
    $validator->after(function ($validator) {
        if ($this->end_level <= $this->start_level) {
            $validator->errors()->add(
                'end_level',
                '終了レベルは開始レベルより大きくしてください。'
            );
        }
    });
}

このように、
複数の値を使った少し複雑な条件などを追加できます。

Form Request全部入り

全部組み合わせると、例えばこんな形になります。

<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class StoreQuestRequest extends FormRequest
{
    // 実行権限を確認
    public function authorize(): bool
    {
        return true;
    }

    // Validation前にデータを整える
    protected function prepareForValidation(): void
    {
        $this->merge([
            'title' => trim($this->title),
        ]);
    }

    // Validationルール
    public function rules(): array
    {
        return [
            'title' => 'required|string|max:255',
            'level' => 'required|integer|min:1',
        ];
    }

    // エラーメッセージ
    public function messages(): array
    {
        return [
            'title.required' => 'クエスト名を入力してください。',
            'level.required' => '推奨レベルを入力してください。',
        ];
    }

    // 項目名
    public function attributes(): array
    {
        return [
            'title' => 'クエスト名',
            'level' => '推奨レベル',
        ];
    }

    // Validation成功後
    protected function passedValidation(): void
    {
        //
    }
}

Controllerは、

use App\Http\Requests\StoreQuestRequest;

public function store(StoreQuestRequest $request)
{
    Quest::create(
        $request->validated()
    );

    return redirect('/quests');
}

だけで済みます。
かなりスッキリしました。


Form Requestの処理イメージ

Codex 画像 2026年8月24日 04_56_42.png

minmaxには注意

ここは少し重要です。

'level' => 'integer|min:3'

なら、
数値として3以上です。

一方、

'title' => 'string|min:3'

なら、
文字列として最低3文字になります。

integer + min
→ 数値の大きさ

string + min
→ 文字数

この変化に注意して使います。

結局どちらを使えばいい?

小さなValidationなら、

$request->validate();

で十分です。

例えば、

public function store(Request $request)
{
    $validated = $request->validate([
        'title' => 'required',
    ]);

    Quest::create($validated);
}

くらいなら非常に読みやすいです。

Validationルールが多い
独自メッセージがある
権限チェックがある
入力値の整形がある
Controllerが長くなってきた

という場合は、
Form Requestに切り出す
ことを検討すると良さそうです。

まとめ

Validationとは

アプリケーションに入ってくるデータがルールを守っているか確認する門番

Laravelでは、

小規模なら

Controller

$request->validate()
でもValidationできます。

処理が大きくなってきたら、

Form Request

Validationを専用クラスへ分離

Controllerがスッキリ

RPG風にまとめるなら、

村人
↓
依頼書を持ってギルドへ

ギルド受付(Validation)
↓
依頼内容をチェック

問題あり
↓
受付拒否

問題なし
↓
受付完了

Controller(勇者)
↓
本来の仕事へ

DB(依頼ボード)
↓
正しい依頼だけ保存

こんな感じです。
勇者に「どこ行ったらええねん」と言わせないためにも、Validationは大事です。

3
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?