アプリケーションのデータが有効かつ正確であるように努めること。そして、すべてのシステム要件を満たすこと。これらの施策は基本的でありながら、その重要性は計り知れません。データの一貫性を維持し、セキュリティの脆弱性を効率的に取り除くことが肝要です。
Laravelでは、データ検証(つまりバリデーション)を直感的に行うことができます。モデル・ビュー・コントローラ(MVC)というアーキテクチャに従い、これの操作には、PHPとオブジェクト指向プログラミング(OOP)の概念に関する一般的な知識さえあれば十分です。さらに、Laravelには入力データを検証する便利なメソッドが複数用意されています。
今回の記事では、覚えておきたいアプローチと、データセットにバリデーションルールを適用する方法をご紹介します。
Laravelで簡単にできるデータバリデーション
Laravelには、フォームに入力されたデータを検証するための、すぐに使えるバリデーションルールが複数用意されています。入力フィールドを必須としてマークしたり、長さの最小値や最大値を設定したり、一意の(重複しない)入力や有効なメールアドレスを要求したりできます。Laravelバリデータによって、入力内容が特定のルールを満たしているかどうかがチェックされます。
Laravelのバリデーションルールには以下のものがあります。
required
:フィールドデータがNULLや空であってはならないarray
:フィールドデータがPHPの配列でなければならないbail
:最初のバリデーションに失敗すると実行を停止email
:フィールドデータが有効なメールアドレスでなければならないunique
:フィールドデータがデータベーステーブル内で重複してはいけない
どのバリデーション方法にも長所と短所がありますが、その多様性により、状況にあった方法を選択することができます。その方法に応じて、Laravelのバリデーションは、手動または自動のエラーメッセージを伴い実行されます。
最も一般的な方法はvalidate
で、HTTPリクエストに対して使用されます。このメソッドがリクエストデータに連結され、バリデーションルールを実行することになります。下の例のように、各フィールドのルールをカンマで区切ることができます。
use Illuminate\Http\Request;
public function store (Request $request){
$validated = $request->validate([
'email' => ['required, unique:users, email, bail'],
'name' => ['required'],
]);
}
ここでは、email
は入力必須であり、NULLは許可されません。さらに、users
データベーステーブルで一意でなければならず、同じメールアドレスが2度登録されないようになっています。最後のルールは、メールアドレスが有効でなければならないというものです。そうでなければ、バリデーションが終了します。nameフィールドは必須ですが、他のルールはありません。
バリデーションルールのいずれかが失敗すると、レスポンスが自動で生成されます。
バリデーションの基本
バリデーションの方法をよりよく理解するために、次の例を考えてみましょう。エンドポイントのルートを定義し、リクエストデータのバリデーションと処理を行うコントローラを作成します。
まず、メールとパスワードを保存できるシンプルなエンドポイントを作ります。
ルートを定義する
Laravelのルートは、ウェブアプリケーションの場合はroutes/web.phpファイル、APIの場合はroutes/api.phpファイルで定義します。この例では、api.phpを使用します。
use App\Http\Controllers\UserController;
Route::post('/store', [UserController::class]);
コントローラの作成
Artisanコマンドを実行して、コントローラを作成します。
php artisan make:controller
UserController
このコマンドによって、app/Http/ControllersディレクトリにUserController.phpファイルが作成されます。
次に、store
メソッドを定義して、ストアエンドポイントに入力されたデータを保存する前に検証を行います。
この例では、以下のルールを使用して以下のフィールドを検証します。
- email:一意であり、有効なメールアドレスであること(必須)
- password:特定の長さがあり、パスワードの確認が行われること(必須)
- age:数値でなければならない(必須)
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class UserController extends Controller
{
/**
* 新規ユーザー情報を保存
*
*/
public function store(Request $request){
$validated = $request->validate([
'email' => 'required|unique:users|email',
'age' => 'required|numeric',
'password' => 'required|min:7|confirmed'
]);
// ユーザーデータの検証後、データを保存するロジック
}
}
confirmed
ルールでは、データが正確であることを確認するために、特定のフィールドを2回要求(登録時にパスワードを再入力させるなど)することができます。このルールでは、password_confirmation
というフィールドを要求しています。このフィールドのデータは、「password」フィールドと一致する必要があります。
エラーメッセージの表示
バリデーションの基準が満たされていれば、コードが正常に実行されます。バリデーションに失敗した場合は、IlluminateValidationValidationException
の例外が投げられ、該当するエラーレスポンスが返されます。
この例はAPIに基づいており、422 Unprocessable Entity
HTTPレスポンスをJSON形式で返します。ウェブアプリケーションの場合は、前のURLにリダイレクトしてエラーメッセージを表示します。尚、その際には、リクエストデータが(フラッシュデータとして)セッションに一時保存されます。
返されたエラーを表示するには、ビューで$errors
変数を使うことができます。
@if ($errors->any())
<div class="alert alert-danger">
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
また、最初のエラーだけを表示したり、ループしてすべてのエラーを表示したりすることもできます。
// すべてのエラーを取得
$errors->all()
// 最初のエラーだけを取得
$errors->first()
フォームの再入力
フォームを再入力することで、ユーザーが情報を再入力する手間を省き、エラーの修正に集中することができます。メールアドレスがエラーになった例では、name
フィールドの古い値を呼び出すことで、フォームの残りの部分を再入力できます。
$name = $request-> old('name')
//Bladeヘルパー
<input type="text" name="name" value="{{ old('name') }}">
このルールは、以前の入力がなければnull
を返します。
高度なバリデーション
Laravelには他にも、フォームリクエストと呼ばれる、バリデーションを記述する方法があります。フォームリクエストはカスタムリクエストクラスであり、バリデーションを整理し、コントローラを宣言するものです。
大量の入力内容に適した独自のバリデーションと認証ロジックを持ち、バリデーションルールの定義やエラーメッセージのカスタマイズに使用できます。
フォームリクエストを作成するには、次のArtisanコマンドを実行します。
php artisan make:request StoreUserRequest
このコマンドは、app/Http/RequestsディレクトリにStoreUserRequest.phpファイルを作成するものです。以下の2つのデフォルトメソッドが含まれます。
rules
:リクエストデータのバリデーションルールを返すauthorize
:対象の操作を実行する権限があるかどうかを示すブール値を返す
前の例をフォームリクエストを使用するように変換してみます。
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class StoreUserRequest extends FormRequest
{
/**
* ユーザーがこのリクエストを行う権限があるかどうかを判断
*
* @return bool
*/
public function authorize()
{
// ユーザーがこのデータを送信する権限があるかどうかをチェックするロジックを追加(trueを返す)
}
/**
* リクエストに適用されるバリデーションルールを取得
*
* @return array<string, mixed>
*/
public function rules()
{
return [
'email' => 'required|unique:users|email',
'age' => 'required|numeric',
'password' => 'required|min:7|confirmed'
];
}
}
このルールのエラーメッセージをカスタマイズするには、FormRequest
クラスのmessagesメソッドをオーバーライドします。
/**
* 定義したバリデーションルールのエラーメッセージを取得
*
* @return array
*/
public function messages()
{
return [
'email.required' => 'An email address is required',
'email.email' => 'The email address must be valid',
'password.confirmed'=>'Re-type your password as
password_confirmation, passwords does not match'
];
}
補足)データ名とバリデーションルールはピリオド(.)で区切られます。
カスタムバリデーション
カスタムバリデーションを作成するには、validate
のかわりにValidator
ファサードを使用します。 バリデータのインスタンスには、バリデーション対象のデータとバリデーションルールの配列という、2つの引数が含まれます。この2つの引数がバリデータファサードの::make
メソッドに渡され、新しいバリデータのインスタンスが生成されます。
use Illuminate\Http\Request;
public function store (Request $request){
$validator = Validator::make($request->all(),[
'email' => 'required|unique:users|email',
'age' => 'required|numeric',
'password' => 'required|min:7|confirmed'
]);
if ($validator->fails()) {
// エラーを返すか、エラーとともにリダイレクトする
return $validator->errors();
}
// 有効な入力内容を取得
$validated = $validator->validated();
// データを保存するロジックの続行
}
自動ダイレクトを追加するには、既存のバリデータインスタンスに対してvalidate
メソッドを実行します。バリデーションに失敗した場合は、XHRリクエストでステータスコード422 Unprocessable Entity
のJSONレスポンスを返します。
$validator = Validator::make($request->all(),[
'email' => 'required|unique:users|email',
'password' => 'required|min:7|confirmed'
])->validate();
Validate::make method
にmessages
という第三引数を渡すことで、エラーメッセージをカスタマイズすることもできます。
$validator = Validator::make($request->all(),[
'email' => 'required|unique:users|email',
'age' => 'required|numeric',
'password' => 'required|min:7|confirmed'
], $messages = [
'required' => 'The :attribute field is required.',
]);
補足):attribute
は検証中のフィールド名に置き換えられます。
まとめ
データバリデーションの実行は、データセットをクリーンで正しく、完全な状態に保つために極めて重要です。データバリデーションを行うことで、プロジェクトに影響を与える可能性のあるデータのエラーを排除することができます。バリデーションは、大規模で大量のデータを扱う場合には、ますます重要になります。
Laravelには、アプリケーションを通過するデータの完全性と正確性を保証するために、数多くの柔軟なアプローチが用意されています。デフォルトのメソッド、またはカスタマイズ対応のメソッドで複雑なバリデーションロジックを実現することができ、コードベースが構造化され、再利用も容易になります。
まだの方は是非ともこの機会に、Kinstaのアプリケーションホスティングサービスを使ってLaravelアプリケーションの高速デプロイをお試しください。
コメントを残す