FuelPHPのValidationにクロージャを使う

  • 28
    いいね
  • 0
    コメント
この記事は最終更新日から1年以上が経過しています。

例としてログインするときのvalidateは大きくわけると以下のとおり。

  • ID(email等)の必須チェック
  • パスワードの必須チェック
  • IDとパスワードでログインできるか

最初の2つはドキュメント通りでいいですが、最後のvalidateは、2つの項目が必要になります。
FuelPHPの基本的なvalidateは、いずれかの項目に対して行うので、ログインチェックのような複数の項目を取り扱うにはちょっと扱いづらいです。
そこで無名関数(Closure)の出番となります。

user.php
<?php
    public static function login_validate()
    {
        $val = Validation::forge();
        $val->add_field('email', 'Email','required');
        $val->add_field('password', 'パスワード', 'required');

        $email = Input::post('email');
        $password = Input::post('password');
        $val->add('dummy', 'dummy')->add_rule(
            function () use ($email, $password) { // login_validate
                if (!$email || !$password) {
                    return true;
                }
                $user = Model_User::query()->
                    where('email', $email)->
                    where('password', $password)->
                    where('del_flg', 0)->get_one();

                if ($user) {
                    return true;
                } else {
                    Validation::active()->set_message('closure', 'ログインに失敗しました。');
                    return false;
                }
            }
        );
        return $val;
    }

「ログイン失敗」のvalidate対象は2項目あるので、対象のフィールドは"dummy"にしています。(使いません)
add_ruleには無名関数が渡せますので、use句で引数を与えましょう。(レキシカル変数)
functionに引数がないのは、addで追加したフィールドを使用しないためです。

emailのフィールドにログイン可否のvalidateを仕込むと以下のようになります。

user.php
<?php
    public static function login_validate()
    {
        $val = Validation::forge();

        $password = Input::post('password');
        $val->add('email', 'Email')
            ->add_rule('required')
            ->add_rule( // login_validate
                function($email) use ($password) {
                    if (!$email || !$password) {
                        return true;
                    }
                    $user = Model_User::query()->
                        where('email', $email)->
                        where('password', $password)->
                        where('del_flg', 0)->get_one();

                    if ($user) {
                        Session::set('login_user', $user);
                        $user->store();
                        return true;
                    } else {
                        Validation::active()->set_message('closure', 'ログインに失敗しました。');
                        return false;
                    }
                });
        $val->add_field('password', 'パスワード', 'required');
        return $val;
    }

無名関数の引数はaddで指定したemail値が渡され、パスワードはレキシカル変数としてclousureに持ちます。
作成したクロージャに再利用性があるなら適当なクラスにクロージャを返すユーザ定義関数作るといいと思います。

という感じにFuelPHPのValidationにクロージャを使うとValidation無双できるよというお話でした。

追記

FuelPHP Advent Calendar 2013にて、バリデーションにClosureを利用する際の注意点を記載しました。
FuelPHPを更に使ってみて使えるなと思った拡張ValidationRuleの書き方とCore拡張の小技