この内容は古いバージョンです。最新バージョンを表示するには、戻るボタンを押してください。
バージョン:13
ページ更新者:guest
更新日時:2026-06-11 07:07:02

タイトル: バリデーション
SEOタイトル: Laravel バリデーション完全ガイド(validate / Form Request / カスタムルール / ローカライズ)

この記事の要点
  • Laravel のバリデーションは $request->validate([...]) が最短。失敗時は自動で 422 か直前ページへ戻る
  • 大規模プロジェクトでは Form Request クラスphp artisan make:request StoreUserRequest)にルールを分離
  • 標準ルールが豊富: required / email / unique:users,email / confirmed / regex:/.../ / exists:users,id
  • カスタムルールphp artisan make:rule Uppercase または Rule::make() クロージャ
  • エラーメッセージは resources/lang/{ja|en}/validation.php でローカライズ。属性名は attributes キーで日本語化

バリデーションの基本: $request->validate()

Laravel で最も簡単なバリデーション方法。コントローラ内で $request->validate() を呼ぶだけで、失敗時は自動的にリダイレクト(HTML)or 422 JSON 応答(API)を返します。

// app/Http/Controllers/UserController.php
public function store(Request $request)
{
    $validated = $request->validate([
        'name'     => 'required|string|max:255',
        'email'    => 'required|email|unique:users,email',
        'password' => 'required|min:8|confirmed',
        'age'      => 'nullable|integer|min:0|max:150',
    ]);

    User::create($validated);
    return redirect()->route('users.index');
}

失敗時は Illuminate\Validation\ValidationException がスローされ、Laravel が以下を自動処理します:

  • HTML リクエスト → 直前ページへリダイレクト + $errors をセッションに格納
  • JSON / Ajax リクエスト → HTTP 422 + エラー JSON を返却

Form Request クラスで分離する

コントローラが肥大化したら Form Request に分離するのがベストプラクティス:

php artisan make:request StoreUserRequest
# → app/Http/Requests/StoreUserRequest.php
// app/Http/Requests/StoreUserRequest.php
namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class StoreUserRequest extends FormRequest
{
    public function authorize(): bool
    {
        return $this->user()->can('create', User::class);
    }

    public function rules(): array
    {
        return [
            'name'     => ['required', 'string', 'max:255'],
            'email'    => ['required', 'email', 'unique:users,email'],
            'password' => ['required', 'min:8', 'confirmed'],
        ];
    }

    public function messages(): array
    {
        return [
            'email.unique' => 'このメールアドレスは既に登録されています。',
        ];
    }

    public function attributes(): array
    {
        return [
            'name'  => '氏名',
            'email' => 'メールアドレス',
        ];
    }
}

コントローラ側は型ヒントするだけで自動的にバリデーションが実行されます:

public function store(StoreUserRequest $request)
{
    // ここに到達した時点でバリデーション済
    User::create($request->validated());
    return redirect()->route('users.index');
}

主要バリデーションルール一覧

ルール説明
required必須項目required
nullablenull 許容(他ルールをスキップ)nullable|integer
string / integer / numeric型チェックinteger|min:1
min / max長さ・値の範囲min:8|max:255
emailメール形式email:rfc,dns
unique:table,columnDB に重複なしunique:users,email
exists:table,columnDB に存在するexists:roles,id
confirmed{field}_confirmation と一致password+password_confirmation
regex:/pattern/正規表現regex:/^[A-Z]+$/
in:a,b,c列挙値in:admin,user,guest
date / date_format:Y-m-d日付date_format:Y-m-d H:i
image / mimes:jpg,pngファイル種別image|mimes:jpg,png|max:2048

Validator::make() を直接使う

Request 以外(コマンド、ジョブ、Livewire 等)でバリデーションしたいときは Validator ファサードを使います:

use Illuminate\Support\Facades\Validator;

$validator = Validator::make($data, [
    'name'  => 'required|max:255',
    'email' => 'required|email',
]);

if ($validator->fails()) {
    return response()->json([
        'errors' => $validator->errors(),
    ], 422);
}

$validated = $validator->validated();

カスタムルール

標準ルールで足りない場合はカスタムルールを作ります:

php artisan make:rule Uppercase
// app/Rules/Uppercase.php
namespace App\Rules;

use Closure;
use Illuminate\Contracts\Validation\ValidationRule;

class Uppercase implements ValidationRule
{
    public function validate(string $attribute, mixed $value, Closure $fail): void
    {
        if (strtoupper($value) !== $value) {
            $fail('The :attribute must be uppercase.');
        }
    }
}

// 使い方
$request->validate([
    'code' => ['required', new Uppercase],
]);

1 行で済むならクロージャでも OK:

$request->validate([
    'title' => [
        'required',
        function (string $attribute, mixed $value, Closure $fail) {
            if (str_contains($value, 'NG')) {
                $fail("{$attribute} に NG ワードが含まれています。");
            }
        },
    ],
]);

エラーメッセージのローカライズ

日本語化は resources/lang/ja/validation.php を配置:

# Laravel 標準の日本語訳パッケージを使う
composer require askdkc/breezejp --dev
php artisan breezejp

# または手動で resources/lang/ja/ を作成
// resources/lang/ja/validation.php
return [
    'required' => ':attribute は必須項目です。',
    'email'    => ':attribute は正しいメールアドレス形式で入力してください。',
    'min'      => [
        'string'  => ':attribute は :min 文字以上で入力してください。',
        'numeric' => ':attribute は :min 以上の数値で入力してください。',
    ],
    'unique'   => ':attribute は既に使用されています。',

    'attributes' => [
        'name'     => '氏名',
        'email'    => 'メールアドレス',
        'password' => 'パスワード',
    ],
];

// config/app.php
'locale' => 'ja',

Blade テンプレートでのエラー表示

@csrf
@error('name') {{ $message }} @enderror
{{-- 全エラーをまとめて表示 --}} @if ($errors->any())
    @foreach ($errors->all() as $error)
  • {{ $error }}
  • @endforeach
@endif

FAQ

Q: API で JSON エラーを返したい
A: Accept: application/json ヘッダ付きならデフォルトで JSON 応答。または app/Exceptions/Handler.phprender() をカスタマイズ。

Q: unique:users,email で更新時に自分自身を除外したい
A: Rule::unique('users', 'email')->ignore($this->route('user')) を使います。

Q: ネストした配列をバリデーションしたい
A: 'items.*.name' => 'required' のようにドット記法 + ワイルドカードでアクセス可能です。