98
98

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

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

Last updated at Posted at 2016-12-05

本記事は 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

ひとこと

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

98
98
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
98
98

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?