Help us understand the problem. What is going on with this article?

Laravel でカスタムバリデーションとそのテスト

More than 1 year has passed since last update.

本記事は Laravel Advent Calendar 2016 の 6 日目の記事です。

はじめに

公式のカスタムバリデーションのドキュメントが今ひとつ分かりにくいので、手順をまとめることにした。
今回はサンプルとして ふりがな のバリデーションを作成する。

※以前に書いた通常バリデーションの応用
http://qiita.com/komatzz/items/422bcba9847ca3a79fe9

環境

  • CentOS 7
  • PHP 7
  • Laravel 5.3

カスタムバリデーション作成手順

サービスプロバイダー作成

php artisan make:provider ValidatorServiceProvider

作成されたクラスを以下のように編集。

app/Providers/ValidatorServiceProvider.php
namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use Domain\CustomValidator;

class ValidatorServiceProvider extends ServiceProvider
{
    /**
     * Bootstrap the application services.
     *
     * @return void
     */
    public function boot()
    {
      \Validator::resolver(function ($translator, $data, $rules, $messages) {
          return new CustomValidator($translator, $data, $rules, $messages);
      });
    }

    /**
     * Register the application services.
     *
     * @return void
     */
    public function register()
    {
        //
    }
}

作成したサービスプロバイダーを設定ファイルに追加

config/app.php
'providers' => [
    ...

    App\Providers\ValidatorServiceProvider::class,

    ...

カスタムバリデーションのロジックを書くファイルを作成する

今回はdomainというディレクトリを作成し、その下にCustomValidator.phpを作成した。

domain/CustomValidator.php
namespace Domain;

class CustomValidator extends \Illuminate\Validation\Validator
{
  /**
  * ふりがなのバリデーション
  *
  * @param $attribute
  * @param $value
  * @param $parameters
  * @return bool
  */
  public function validateKana($attribute, $value, $parameters)
  {
      if (mb_strlen($value) > 100) {
          return false;
      }  

      if (preg_match('/[^ぁ-んー]/u', $value) !== 0) {
          return false;
      }

      return true;
  }
}

オートロードの設定

composer.json の psr-4 設定に にdomainディレクトリ配下をオートロードできるように追加する
※これに気づかなくてハマった

composer.json
...

"autoload": {
  "psr-4": {
      "App\\": "app/",
      "Domain\\": "domain/",
  }
}

...

エラーメッセージファイルに追加

resources/lang/ja/validation.php
return [
   ...

   'kana' => ':attributeはひらがなで入力をしてください。',

   ...

   'attributes' => [
       ...

        'family_name_kana' => 'ふりがな(せい)',
        'given_name_kana'  => 'ふりがな(めい)',

       ...
   ],

カスタムバリデーションを使う

使い方は通常のバリデーションと同じで、
'family_name_kana' => 'required|kana',
のように使いたいバリデーションを|区切りで指定すれば良い。

app/Http/Controllers/RegistersController.php
namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Http\Requests;
use App\Http\Controllers\Controller;
use Validator;

class RegistersController extends Controller
{
    ...

    public function confirm(Request $request, $registerToken)
    {
        \Validator::make(
            [
                'family_name_kana' => trim($request->get('family_name_kana')),
                'given_name_kana'  => trim($request->get('given_name_kana')),
            ],
            [
                'family_name_kana' => 'required|kana',
                'given_name_kana'  => 'required|kana',
            ]
        }->validate();
    }
    return view('registers/registers_confirm');

    ...
}

バリデーション実施結果

valid_kana.png

ふりがな(せい)をカタカナで POST したので、ちゃんと引っかかっている。

テストコード作成

ちゃんとバリデーションできているかどうかテストするコードを書く。

tests/domain/validation/KanaTest.php
<?php

/**
 * かなのバリデーションのテストクラス
 */

namespace Tests\Domain\Validation;

use Validator;

class KanaTest extends \TestCase
{
    /**
     * 正常系テスト
     *
     * @dataProvider successParamsProvider
     * @param array $values
     */
    public function testSuccess($values)
    {
        $validator = \Validator::make(
            [
                'family_name_kana' => $values,
                'given_name_kana'  => $values,
            ],
            [
                'family_name_kana' => 'required|kana',
                'given_name_kana'  => 'required|kana',
            ]
        );

        $this->assertTrue(
            $validator->passes()
        );
    }

    /**
     * 正常系パラメータ用のデータプロバイダー
     *
     * @return array
     */
    public function successParamsProvider()
    {
        return [
            'ひらがな' => [
                'やきにくていしょく',
            ],
            '大きな文字列(かなは100文字まで)' => [
                str_repeat('あ', 100)
            ],
        ];
    }

    /**
     * 異常系テスト
     *
     * @dataProvider failParamsProvider
     * かなに不適切な文字が入力されている
     *
     * @param array $values
     */
    public function testFail($values)
    {
        $validator = \Validator::make(
            [
                'family_name_kana' => $values,
                'given_name_kana'  => $values,
            ],
            [
                'family_name_kana' => 'required|kana',
                'given_name_kana'  => 'required|kana',
            ]
        );

        $this->assertTrue(
            $validator->fails()
        );
    }

    /**
     * 異常系パラメータ用のデータプロバイダー
     *
     * @return array
     */
    public function failParamsProvider()
    {
        return [
            '数字' => [
                1,
            ],
            '漢字' => [
                '焼肉定食',
            ],
            'カタカナ' => [
                'ヤキニクテイショク',
            ],
            '大きな文字列(かなは100文字まで)' => [
                str_repeat('あ', 101),
            ],
            'NULL' => [
                null,
            ],
            '空' => [
                '',
            ],
            'スクリプト' => [
                '<script>alert(1);</script>',
            ],
            '\'' => [
                '\'',
            ],
            '/' => [
                '/',
            ],
            '<' => [
                '<',
            ],
            '¥' => [
                '¥',
            ],
        ];
    }
}

解説

  • ひらがな かつ、100文字以内かどうかをテストしている
  • PHPUnit のデータプロバイダーという機能を使うと簡潔にテストコードが書けて、失敗したときにどこで失敗したのか分かりやすい

image

ひとこと

これでバリデーション処理に関しては、ほとんど対応できるようになった。

kamakura-net
株式会社鎌倉新書は、さまざまな情報を集めて提供する、情報加工会社です。人々の織りなす不思議な縁と、その美しく強い結びつきのお手伝いをすることにより、私たちの企業と私たちの社会の発展、繁栄に貢献することを経営理念としています。
https://www.kamakura-net.co.jp
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした