WebサイトやWebアプリにおいてユーザーが入力すためのフォームを目にすることや利用することは多いのではないでしょうか?
このフォームにユーザーが何でもかんでも入力していいわけではありません。サイト作成者が意図しない値をユーザーが入力する場合はできるだけ避けなければなりません。
そのためにユーザーがフォームに入力できる値を制限することをバリデーションと言います。
Laravelではバリデーションをかけるための方法がいくつか存在します。その中でも、FormRequest
を使ったバリデーション方法をこの記事では紹介していきたいと思います。
入力フォームの作成
リクエストを送るためのフォームを作っていきましょう。
まずはコントローラーの作成です。FormController
というコントローラーを作ります。
php artisan make:controller FormController
作成したFormController.phpの中身を下記の通りに実装します。
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class FormController extends Controller
{
public function index()
{
return view('form.index');
}
}
Viewを返すだけの単純なコードです。
また、ルーティングの設定もしておきます。
Route::get('/form', 'FormController@index');
次にform/index.blade.phpを作成していきましょう。
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="csrf-token" content="{{ csrf_token() }}">
<title>Laravel</title>
<!-- Fonts -->
<link href="https://fonts.googleapis.com/css2?family=Nunito:wght@200;600&display=swap" rel="stylesheet">
<link href="{{ mix('css/app.css') }}" rel="stylesheet" type="text/css">
</head>
<body>
<form action="/form/test" method="POST">
@csrf
<input type="text" name="message">
<button type="submit" class="btn btn-primary">送信</button>
</form>
<script src="{{ mix('js/app.js') }}"></script>
</body>
</html>
form
タグの中に入力用のinput
タグと送信用のボタンを配置しています。
また、@csrf
という記述がありますね。
これはLaravelが標準で使えるようにしているCSRF対策で、フォームでリクエストを送る際にはこちらの記述をしないと下記のようなエラー画面となります。
@csrf
の記述をすることで、リクエストが送信できるようになります。
ですが、このままではどんな値でも入力できてしまいますね。
入力を制限するようにバリデーションをかけていきましょう。
FormRequestを継承したClass
FormRequestとはRequestファサードを継承したもので、バリデーションのルールやメッセージをカスタマイズするのに特化しています。コントローラーやモデルから切り分けることで、可動性や保守性を上げることも期待できます。
FormRequest
のクラスであるTestRequestを
コマンドで作成します。
php artisan make:request TestRequest
作成されたTestRequest.phpのファイルの中身は下記のようになっています。
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class TestRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return false;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
//
];
}
}
FormRequest
クラスを継承したTestRequest
の中にauthorize
メソッドとrules
メソッドが定義されているのが、分かりますね。
authorizeメソッド
boolean
型のfalse
が戻り値として返しています。
このauthorize
メソッドはTestRequest
の使用を許可するどうかを設定するためのメソッドです。false
が設定されているということはデフォルトでは使用許可されていない状態です。
rulesメソッド
戻り値として空の配列をしているところに、バリデーションを定義していきます。
messagesメソッド
また、フォームリクエストを作成したデフォルトの状態では定義されていませんが、messages
メソッドを定義することができます。messages
メソッドではバリデーションエラー時のエラー文を定義することができます。rules
メソッド同様に配列形式で戻り値を返す必要があります。
バリデーションの作成
それではバリデーションを実際に実装していきましょう。
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class TestRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'message' => 'required'
];
}
/**
* @return array
*/
public function messages()
{
return [
'message.required' => '必ず何か入力してください。'
];
}
}
1つずつ解説していきます。
public function authorize()
{
return true;
}
authorize
メソッドでtrue
を戻り値として返すことで、TestRequest
の利用を許可します。
public function rules()
{
return [
'message' => 'required'
];
}
rules
メソッドの戻り値である連想配列のキーにはinput
タグのname
属性の値を指定します。
値にはinput
タグにかけたいバリデーションルールを指定します。required
を指定するとそのinput
タグは空にすることは出来ず、必須項目とすることが出来ます。
もちろん、バリデーションルールはrequired
だけでなく、数多くあります。バリデーションルールの一覧はLaravelの公式ドキュメントで掲載されていますので、ぜひ参考にしてください。
Laravel 7.x バリデーション(https://readouble.com/laravel/7.x/ja/validation.html)
public function messages()
{
return [
'message.required' => '必ず何か入力してください。'
];
}
messages
メソッドでは、rules
メソッドで制限したバリデーションルールに対してエラーだった場合のエラーメッセージをカスタマイズすることができます。messages
メソッドの戻り値の連想配列のキーにはrules
メソッドで定義した連想配列の「キー」.「値」として指定します。
値にその時のエラーメッセージを指定することが出来ます。
また、エラーメッセージは送信元のviewで下記のように記述することでエラーが発生したときに表示することが出来ます。
<div>{{ $errors->first('message') }}</div>
コントローラーの編集
バリデーションの作成をすることが出来ましたが、このままではバリデーションを使用することが出来ていません。
コントローラーで作成したバリデーションを使用するように紐づけをしてあげる必要があります。
それではコントローラーを編集していきましょう。
<form action="/form/test" method="POST">
@csrf
<input type="text" name="message">
<button type="submit" class="btn btn-primary">送信</button>
</form>
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
...省略...
</head>
<body>
<p>{{ $message }}</p>
<script src="{{ mix('js/app.js') }}"></script>
</body>
</html>
Route::post('/form/test', 'FormController@test');
public function test(Request $request)
{
return view('form.test', ['message' => $request->message]);
}
今回、FormController
のtest
メソッドがフォームからのリクエストを受けるメソッドとして定義しました。Request
クラスでフォームからの値を受け取ることが出来ましたね。
バリデーションを適用させる場合は、Request
クラスではなく先ほど作成したTestRequest
クラスで受け取るように定義することで紐づけることができます。
use App\Http\Requests\TestRequest;
class FormController extends Controller
{
...省略...
public function test(TestRequest $request)
{
return view('form.test', ['message' => $request->message]);
}
}
これでフォームリクエストでのバリデーションの実装が出来ました。
挙動を確認してみましょう。
何も入力せずに、送信ボタンを押下してみましょう。
TestRequest
クラスのmessages
メソッドで定義したエラーメッセージが無事に表示されています。
まとめ
Laravelのフォームリクエストを使ってバリデーションを行う方法を解説してきました。
少しやることが多いなと感じた方もいるかもしれませんが、この機能は非常に便利です。
フレームワークなど無しでバリデーションを行おうとすれば、if文や正規表現などを駆使してアルゴリズムを定義する必要があり、とても大変です。
そういったことなしにバリデーションを行えるLaravelのフォームリクエストは非常に便利です。
バリデーションはWebシステム開発において必須の機能なので、ぜひフォームリクエストを使いこなして開発効率を上げていきましょう。