Laravelのバリデーション拡張を作った
LaravelでWebアプリを書いていて、ややバリデーション周りの機能が薄いと感じたので拡張パッケージを書きました。
Laravel標準のバリデーションについては公式のドキュメントを見ればいいかと思います。この場合Validator::make
メソッドに入力データ、バリデーションルール、デフォルトから変える必要があるならエラー時のメッセージ、をそれぞれ配列で渡してvalidator
オブジェクトを作成し、その後fails
メソッドで検証が通るかどうかを確認します。例えば以下のようなコードになります。
<?php $rules = array( 'username' => 'required|alpha', 'password' => 'required|alpha|min:8', ); $validator = Validator::make(Input::all(), $rules); if ($validator->fails()) { return Redirect::back()->withErrors($validator); }
シンプルなのはいいのですが、実際のアプリケーションを書くとなると更に以下のようなことがしたくなります。
- バリデーションルールの定義箇所をメインロジックから個別のクラスに外出ししたい。
- バリデーションの前後で値の変換処理を行いたい。例えばバリデーションの前に値をtrimしたり年月日で個別のフィールドに入力された値を結合して日付形式にするなど。
このへんの仕組みが標準では用意されていなかったので、前述の拡張を書きました。
使い方
バリデータクラスをこんな感じに定義して。。。
<?php // app/validators/BlogValidator.php class BlogValidator extends BaseValidator { protected function configure() { $this ->rule('title', 'required', 'Title is required.') ->rule('title', 'max:100', 'Title must not be greater than 100 characters.') ->rule('body', 'pass') ; } }
以下のように使います。
<?php $validator = BlogValidator::make(Input::all()); if ($validator->fails()) { return Redirect::back()->withInput(Input::all())->withErrors($validator); } $data = $validator->onlyValidData();
バリデーション定義がメインロジックから切りだされてスッキリ。
また$validator->onlyValidData
メソッドはバリデートが行われた項目の値のみを配列で戻すメソッドなので、DB更新時などはこの値をEloquentモデルのマスアサインメントでまるっと設定してやればいいかと思います。
フィルタとカスタムバリデーションルール
バリデーション前後に何らかの処理を入れたいときはbeforeFilter
とafterFilter
にクロージャを登録します。
<?php class BlogValidator extends BaseValidator { protected function configure() { $this->beforeFilter(function($validator){ // your code }); $this->afterFilter(function($validator){ // Modify title after validation. $title = $validator->title; $title .= " created by kohki"; $validator->title = $title; }); } }
独自のバリデーションルールを定義したいときはvalidateXXX
というメソッドを作ればOKです。メソッドの規約は標準のカスタムバリデーションルールの定義方法を同じですので、公式ドキュメントを参考にしてください。
<?php class BlogValidator extends BaseValidator { protected function configure() { $this ->rule('title', 'required', 'Title is required.') ->rule('title', 'max:100', 'Title must not be greater than 100 characters.') ->rule('body', 'foo', 'Body must be foo only!') ; } protected function validateFoo($attribute, $value, $parameters) { return $value == 'foo'; } }
インストール方法
composerでインストールします。composer.json
に以下を記述して
"require": { "kohkimakimoto/laravel-validator-extension": "0.*" }
composer updateします。
$ composer update
ServiceProviderとBaseValidatorのエイリアスをapp/config/app.php
に登録します。
'providers' => array(
...
'Kohkimakimoto\ValidatorExtension\ValidatorExtensionServiceProvider',
}
'aliases' => array( ... 'BaseValidator' => 'Kohkimakimoto\ValidatorExtension\Validator', ),
また、私は今のところapps/validators
ディレクトリを切ってそこに個々のバリデータクラスを作成しているので、オートロードされるようにLaravel(app/start/global.php
)とcomposer(composer.json
)にオートロード設定を追加します。
ClassLoader::addDirectories(array( ... app_path().'/validators', ));
"autoload": { "classmap": [ ... "app/validators" ] }
Laravelかわいいよ、Laravelヽ(´ー`)ノ