Laravelでフォームバリデーションを行う際、エラーが発生すると入力フォームに前回の値(old値)が自動的に反映される仕組みがあります。しかし、環境や実装方法によっては、古い入力値がフォームに表示されないという問題が起きることがあります。
この記事では、その原因と対処法を詳しく解説します。
old()関数が機能しない主な原因
old()関数は、セッションに一時保存された入力値を取得して表示する関数です。バリデーションに失敗したとき、Laravelは自動的にセッションに入力値をフラッシュしますが、以下のようなケースでは正しく動作しないことがあります。
セッションが有効になっていない
Laravelでは、old()の動作にセッションが必要です。セッションが無効、または正しく設定されていない場合、入力値は保持されません。
対処法:
webミドルウェアグループが適用されているか確認します。
例えば、ルート定義で以下のようにwebグループに含まれているかチェックします。
Route::middleware(['web'])->group(function () {
// フォームのルート定義
});
config/session.php の設定を確認し、セッションドライバーが正しく設定されていること(file, database, redis など)。
フォームのHTTPメソッドがGETになっている
old()はPOSTリクエストで送信されたデータしか保持しません。GETリクエストではセッションに保存されないため、old()で取得することができません。
対処法:
フォームのメソッドをPOSTに設定してください。
<form method="POST" action="/submit">
@csrf
<input type="text" name="name" value="{{ old('name') }}">
</form>
リダイレクト先でold値を使う前に直接表示している
バリデーションエラー後にリダイレクトされない場合、セッションがリフラッシュされないため、old()が機能しません。
対処法:
return redirect()->back()->withInput(); を使って、入力値をセッションにフラッシュします。
これはコントローラーで手動バリデーションを行う場合に必要です。
if ($validator->fails()) {
return redirect()->back()->withErrors($validator)->withInput();
}
フォームリクエストバリデーション(FormRequestクラス)を使う場合は、Laravelが自動でwithInput()を処理してくれます。
Bladeテンプレートでの記述ミス
old()を使っていても、フォームに設定されているname属性と一致しない場合は反映されません。
対処法:
入力値のキーと一致するように確認します。
<input type="text" name="email" value="{{ old('email') }}">
対応後の正しいフォーム記述例
<form method="POST" action="{{ route('register') }}">
@csrf
<input type="text" name="name" value="{{ old('name') }}">
@error('name')
<div class="error">{{ $message }}</div>
@enderror
<input type="email" name="email" value="{{ old('email') }}">
@error('email')
<div class="error">{{ $message }}</div>
@enderror
<button type="submit">送信</button>
</form>
まとめ
Laravelのold()関数が機能しない場合、セッション設定やフォームのメソッド、バリデーション後のリダイレクト処理などに原因がある可能性があります。正しく設定すれば、ユーザーの入力値を失わず、UXの高いフォームを実装することが可能です。
トラブル時は、ルーティング、セッション設定、HTTPメソッド、リダイレクトのフローを見直すことで解決できる場合が多いので、チェックポイントとして覚えておくと安心です。