Laravelでバリデーションを定義する | A Day In The Boy's Life

A Day In The Boy's Life

とあるエンジニアのとある1日のつぶやき。

Laravelで入力フォームのエラーチェックをしたいといった場合に、標準のバリデーションを利用すれば独自にロジックを組み込むことなく容易に実装することが可能です。

ってことでLaravel標準のバリデータの使い方のまとめです。

ここでは、Laravel4.2をベースに書いています。



Laravel標準のバリデータを利用する


どういったバリデータが標準で用意されているのかを知りたければ、エラーの際に出力されるメッセージの一覧の定義ファイルを見るのが早 いかもしれません。


<?php

return array(
    /*
    |--------------------------------------------------------------------------
    | バリデーション言語行
    |--------------------------------------------------------------------------
    |
    | 以下の言語行はバリデタークラスにより使用されるデフォルトのエラー
    | メッセージです。サイズルールのようにいくつかのバリデーションを
    | 持っているものもあります。メッセージはご自由に調整してください。
    |
    */
    "accepted"             => ":attributeを承認してください。",
    "active_url"           => ":attributeが有効なURLではありません。",
    "after"                => ":attributeには、:date以降の日付を指定してください。",
    "alpha"                => ":attributeはアルファベッドのみがご利用できます。",
    "alpha_dash"           => ":attributeは英数字とダッシュ(-)及び下線(_)がご利用できます。",
    "alpha_num"            => ":attributeは英数字がご利用できます。.",
    "array"                => ":attributeは配列でなくてはなりません。",
    "before"               => ":attributeには、:date以前の日付をご利用ください。",
    "between"              => array(
        "numeric" => ":attributeは、:minから:maxの間で指定してください。",
        "file"    => ":attributeは、:min kBから、:max kBの間で指定してください。",
        "string"  => ":attributeは、:min文字から、:max文字の間で指定してください。",
        "array"   => ":attributeは、:min個から:max個の間で指定してください。",
    ),
    "boolean"              => ":attributeには、trueかfalseを指定してください。",
    "confirmed"            => ":attributeと、確認フィールドとが、一致していません。",
    "date"                 => ":attributeには有効な日付を指定してください。",
- snip -

配列のキーがバリデーションのルールとなっており、ルールに違反した場合は配列の値に格納されているメッセージが出力されます。

例えば、入力項目がアルファベットのみであるかのチェックや指定の日付の正当性のチェックなどのルールが含まれています。

まぁ、boolean型かどうかのチェックでエラーを出すかなど、使うのかどうか疑問なルールもあるわけですが、取りあえず標準としては一般的に使いそうなバリデーションが定義されています。


また、これは日本語化された定義ファイルになりますが、laravel/app/lang/enディレクトリの中にも英語がベースとなっているメッセージ定義ファイルがあります。

この使い分けは、laravel/app/config/app.php内のロケールの定義に依存します。


    /*
    |--------------------------------------------------------------------------
    | アプリケーションローカル設定
    |--------------------------------------------------------------------------
    |
    | アプリケーションローカルは翻訳サービスプロバイダーにより使用される
    | デフォルトローカルを指定します。アプリケーションで提供するローカルを
    | 自由に設定してください。
    |
    */

    'locale' => 'ja',

    /*
    |--------------------------------------------------------------------------
    | アプリケーションフォールバック言語
    |--------------------------------------------------------------------------
    |
    | フォールバック言語は現在のローカルが使用できない場合に、
    | 代替として使われます。アプリケーション全体に対して用意されている
    | 言語フォルダーに対応するコードであればどれでも使用可能です。
    |
    */

    'fallback_locale' => 'en',

上記のように設定することで標準はja(日本語)のロケールが設定され、それが存在しない場合にen(英語)が呼び出されます。

他の言語にローカライズしたい場合は、新たなロケールとメッセージファイルを用意します。


で、具体的なバリデーションの実装方法ですが、まずはバリデーション用のファイルを作りそれを読み込むようにします。

バリデーションファイルへのパスの通し方は「Laravelで独自に作ったライブラリファイルへのパスの通し方 」を参照。


class MyValidator
{
    public function validate (array $params)
    {
        $validator = Validator::make($params, ['id' => 'required|max:10', 'passwd' => 'required_if:flg,1|alpha_num']);
        // バリデーションチェック
        if (!$validator->passes()) {
            $this->errors = $validator->messages();
            return false;
        }
        return true;
    }

    public function errors()
    {
        return $this->errors;
    }
}

バリデーションの作り方はValidator::make()で作成し、チェック対象の引数とその配列内のキーにそれぞれバリデーションのルールを渡します(複数のルールを適用したければパイプで区切ります)。

例えば、idのパラメータは必須(required)でかつ最大10文字(max:10)であるかをチェックしています。

passwdパラメータでチェックしているrequired_ifは特殊でflgが1の場合に必須かどうかをチェックするというものです。

詳細は、マニュアル のほうも確認してみてください。


このバリデーションを元に実際にチェックしてみたいと思います。

コントローラファイルから先ほど作ったバリデーションを呼び出してエラーがあるかどうかをチェックします。


public function foo()
{
    $obj = App::make('MyValidator');
    // リクエストパラメータを取得
    $params = Input::all();
    // バリデータにパラメータを渡してチェック
    if (! $obj->validate($params)) {
        // エラーがある場合は何がしかのエラー画面を出力
        return View::make('Common::Error.index')->withErrors($obj->errors());
    }
    return View::make('hello');
}

エラーがある(validate()からfalseが返ってくる)場合は専用のエラー画面を出力していますが、この辺はお好みで。



バリデーションをカスタマイズする


当然、デフォルトで用意しているバリデーションだけではアプリケーションの要件を満たさない場合がありますし、もっと複雑なバリデーシ ョンを作りたいという場合があります。

この場合、バリデーションルールを独自に作ることができます。

例えば、先ほどのvalidate()に独自のルールを追加してIDのチェック用にDBのマスタ上に存在するかといった処理を加えたルールを追加して みます。


public function validate (array $params)
{
    // バリデータのルールを定義
    Validator::extend('idCheck', function ($attribute, $value, $parameters, $validator) {
        // IDが存在するかどうか
        $db = App::make('DbMaster');
        if (!$db->checkMember($value)) {
            return false;
        }
        // 全パラメータを取得
        $data = $validator->getData();
        // flgが1の場合のみの処理を何か
        if ($data['flg'] === "1" && $db->checkSomething($value)) {
            return false;
        }
        return true;
    });
    // エラーメッセージ
    $messages = array(
        'id_check' => ':attributeが存在しません'
    );
    // 項目名
    $attributes = array(
        'id' => 'ログインID'
    );
    $validator = Validator::make($params, [
        'id' => 'required|max:10|id_check',
        'passwd' => 'required_if:flg,1|alpha_num'
        ], $messages);
    $validator->setAttributeNames($attributes);
    // バリデーションチェック
    if (!$validator->passes()) {
        $this->errors = $validator->messages();
        return false;
    }
    return true;
}

バリデーションルールの拡張はValidator::extend()で行い、第1引数にルール名(idCheck)を指定します。

第2引数は無名関数として定義しており、中身に詳細なバリデーションロジックを記述します。

単純な話、何らかの処理をして最終的に正しければtrueを、誤りがある場合はfalseを返せばよいだけです。


その他のパラメターと複合的にチェックしたい場合、無名関数の第4引数にある$validatorのgetData()メソッドでその他のパラメータを受け 取れたりします。


// 全パラメータを取得
$data = $validator->getData();

拡張したルールは、それに対応するエラーメッセージや項目名を定義する必要があります。

エラーメッセージはルール名をスネークケース(idCheckをid_checkにする)にしたキーを元に配列に格納します。


// エラーメッセージ
$messages = array(
    'id_check' => ':attributeが存在しません'
);

項目名は、エラーメッセージ内の項目名に何を入れるかを定義します。

この際の項目名は、チェックするパラメータ名をキーにしておきます。


// 項目名
$attributes = array(
    'id' => 'ログインID'
);

要は、このバリデーションに引っかかった場合は「ログインIDが存在しません」というエラーメッセージを受け取ることができます。


最後に、定義したルールを適用します。


$validator = Validator::make($params, [
    'id' => 'required|max:10|id_check',
    'passwd' => 'required_if:flg,1|alpha_num'
    ], $messages);
$validator->setAttributeNames($attributes);

最初のバリデーションとは異なり、idのパラメータに適用するバリデーションとしてid_checkが追加されています。

エラーメッセージの設定は、Validator::make()の第3引数に渡し、項目名はsetAttributeNames()によってセットします。


バリデーションのカスタマイズは標準のValidatorそのものを拡張するやり方もあったりするのですが、長くなったので別途まとめたいと思います。