NEWS ABOUT Solution WORKS TEAM BLOG お問い合わせ JP EN

LaravelのValidateの使い方を調べてみた:その3

こんにちは、システムエンジニアの今井です。

前回のブログでLaravelのValidateで「Requestクラスのvalidateメソッドを使う方法」を紹介しました。

Controllerファイル内にvalidateする処理を書くとvalidateする項目数が増えるにつれControllerファイルのコードが肥大化してしまいます。
今回は、validateする処理を外部ファイル化しControllerファイルがスリムになるように「Requestクラスを継承して使う方法」について書いてみたいと思います。

今回紹介するすべてのvalidationは、これまでと同様に以下4つのPOST値をチェックする前提で説明します。
email:必須、email形式
name:必須、255文字以内
title:任意、255文字以内
message:任意、1000文字以上、6000文字以内

環境情報
CentOS 7.7.1908
PHP 7.3.11
Laravel 6.4.0
composer 1.9.1

それでは、「Requestクラスを継承して使う方法」について紹介したいと思います。

①:Laravel自体を作成

composerを使って以下のコマンドを叩くと、実行したコマンドのカレントディレクトリにlaravel_sampleというディレクトリが作成されます。

composer create-project "laravel/laravel=6.4.0" --prefer-dist laravel_sample

②:HogeController.phpの作成

※:以下の作業を行うとapp/Http/Controllers配下にHogeController.phpが作成されます。

cd laravel_sample
php artisan make:controller HogeController

③:HogeRequest.phpの作成

※:Requestクラスを継承するためのHogeRequestを作成します。app/Http/Requests配下にHogeRequest.phpが作成されます。

cd laravel_sample
php artisan make:request HogeRequest

④:routes/web.php

以下の設定で
/hogeのURLを開いた時にHogeControllerのindexアクションを呼び出します。
/hogeのURLにPOST通信したときにHogeControllerのpostアクションを呼び出します。

Route::get('hoge', 'HogeController@index');
Route::post('hoge', 'HogeController@post');

⑤:resources/view/hoge/index.blade.php の作成

/hogeのURLを開いた時に表示されるHTMLになります。
Bootstrap4.3.1を使っています。
{{old(‘xx’)}}はvalidationでエラーになった時に直前に入力していた値を表示します。
$errorsの箇所はエラーメッセージを表示します。

<!doctype html>
<html lang="ja">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/>
<meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no, width=device-width">
<title></title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
</head>
<body>
<div class="container">
<form action="/hoge" method="post">
{!! csrf_field() !!}
<div class="form-group">
  <label for="email">email:</label>
  <input type="text" name="email" id="email" class="form-control" value="{{old('email')}}">
  @if ($errors->has('email'))
  <span class="text-danger">{{$errors->first('email')}}</span>
  @endif
</div>
<div class="form-group">
  <label for="name">name:</label>
  <input type="text" name="name" id="name" class="form-control" value="{{old('name')}}">
  @if ($errors->has('name'))
  <span class="text-danger">{{$errors->first('name')}}</span>
  @endif
</div>
<div class="form-group">
  <label for="title">title:</label>
  <input type="text" name="title" id="title" class="form-control" value="{{old('title')}}"/>
  @if ($errors->has('title'))
  <span class="text-danger">{{$errors->first('title')}}</span>
  @endif
</div>
<div class="form-group">
  <label for="message">message:</label>
  <textarea name="message" id="message" class="form-control">{{old('message')}}</textarea>
  @if ($errors->has('message'))
  <span class="text-danger">{{$errors->first('message')}}</span>
  @endif
</div>
<button class="btn btn-primary" type="submit">Submit form</button>
</form>
</div>
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
</body>
</html>

⑥:resources/view/hoge/post.blade.php の作成

このファイルはvalidateを通過した時に表示されるページになります。POSTしたデータの内容が表示されます。

<!doctype html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<div>
POST成功
<table>
<tr>
<td>email</td>
<td>{{$validated['email']}}</td>
</tr>
<tr>
<td>name</td>
<td>{{$validated['name']}}</td>
</tr>
<tr>
<td>title</td>
<td>{{$validated['title']}}</td>
</tr>
<td>message</td>
<td>{{$validated['message']}}</td>
<tr>
</table>

</div>
</body>
</html>

⑦:app/Http/Controllers/HogeController.phpを編集

<?php

namespace App\Http\Controllers;

use App\Http\Requests\HogeRequest;

class HogeController extends Controller
{
    public function index()
    {
        return view('hoge.index');
    }
    public function post(HogeRequest $request)
    {
        $validated = $request->validate();
        return view('hoge.post')->with(['validated'=>$validated]);
    }
}

⑧:app/Http/Requests/HogeRequest.phpを編集

<?php
namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class HogeRequest extends FormRequest
{
    public function authorize()
    {
        return true;
    }

    public function rules()
    {
        return [
            'email'  => ['required', 'email'],                  // emailフィールドは必須チェック、emailの形になっているかチェックを行う
            'name'   => ['required', 'max:255'],                // nameフィールドは必須チェック、255文字以内かをチェックする
            'title'  => ['nullable', 'max:255'],                // titleフィールドは任意入力、入力があった時は255文字以内かをチェックする
            'message'  => ['nullable', 'min:1000', 'max:6000'], // messageフィールドは任意入力、入力があった時は1000文字以上かつ6000文字以内かをチェックする
        ];
    }

    public function messages()
    {
        return [
            'email.required'   => 'メールアドレスを入力してください。',            // emailフィールドで入力がなかった時に表示されるエラーメッセージ
            'email.email'      => '正しいメールアドレスを入力してください。',      // emailフィールドで正しいemail形式でなかった時に表示されるエラーメッセージ
            'name.required'    => '名前を入力してください。',                      // nameフィールドで入力がなかった時に表示されるエラーメッセージ
            'name.max'         => '名前は:max文字以内で入力してください。',        // nameフィールドで255文字を超えた時に表示されるエラーメッセージ
            'title.max'        => 'タイトルは:max文字以内で入力してください。',    // titleフィールドで255文字を超えた時に表示されるエラーメッセージ
            'message.min'      => 'メッセージは:min文字以上で入力してください。',  // messageフィールドで1000文字未満の時に表示されるエラーメッセージ
            'message.max'      => 'メッセージは:max文字以内で入力してください。',  // messageフィールドで6000文字を超えた時に表示されるエラーメッセージ
        ];
    }
}

以上で、実装までが完了しました。
前回のブログのHogeControllerと比べてのpost()メソッドの中身がかなりすっきりしました。
⑨からはこれを動作してみます。

⑨:以下のコマンドで 8000番ポートにアクセスできるようにします。

php artisan serve --host 0.0.0.0

⑩:ブラウザで8000番ポートで/hogeにアクセスします

⑨のコマンドを行ったサーバのIPアドレスが192.168.1.30として以下のURLでアクセスします。
http://192.168.1.30:8000/hoge
注)サーバで8000番ポートがiptablesやfirewalld等で閉じている場合は、あらかじめ開けておいてください。

以下のようなフォームが表示されます。
WS000281

⑪:空っぽでSubmitボタンを押してみます

メールアドレスと名前の箇所は必須入力ですので、この2つでエラーが表示されました。
WS000282

⑫:その他のエラーを出してみる

メールアドレスにふさわしくない形、名前に255文字以上、タイトルに255文字以上、メッセージに1000文字未満をいれてSubmitしてみます。条件に合わないのでエラーが表示されます。
WS000283

⑬:正しい内容の値を入力しvalidateを通過してみます

以下のように正しい内容の値を入れてSubmitします。
WS000284
Submitするとpost.blade.phpの内容が表示され、validateを通過することが確認できました。
WS000285

まとめ

Requestクラスを継承したHogeRequestクラスを作成して、validateする処理をHogeRequestにもたせることによって、HogeControllerの中身がスッキリすることが出来ました。

3つ続けてLaravelのValidateについて書かせて頂きました。
同じ処理をするにも色々な方法がありました。

Lravelは非常に多機能でvalidate処理は今回紹介した3つだけでなく別のやり方もできそうでした。

案件に応じて色々なやり方を試してみるのもいいかもですね。

今井 健一朗
ひとつ前の投稿 ひとつ前の投稿
ひとつ前の投稿 ひとつ前の投稿 LaravelのValidateの使い方を調べてみた:その2