Zend_Filter_Input を使ってみる
入力した値のバリデーションには Zend_Validate_* を使用すると簡単に入力チェックができる。
例えば、hoge という入力フォームがあって、そこは必須で、4文字以上10文字未満なんて条件を書くと以下のようになる。
<?php $param = $this->_getParam('hoge'); require_once 'Zend/Validate.php'; // My_Validate_NotEmpty は Zend_Validate_NotEmpty を継承したクラス // 0 を Null と判定しない require_once 'My/Validate/NotEmpty.php'; require_once 'Zend/Validate/StringLength.php'; $validateEmpty = new My_Validate_NotEmpty(); $validateEmpty->setMessage('hoge は必須です。'); $validateStringLength = new Zend_Validate_StringLength(4, 10); $validateStringLength->setMessage('4文字以上10文字以下で入力して下さい。'); $chain = new Zend_Validate(); $chain->addValidator($validateEmpty) ->addValidator($validateStringLength); if (!$chain->isValid($param)) { $this->_request->setParam("error", $chain->getMessages()); }
バリデータをチェインとして登録して一気に入力チェックを行ってくれる。
簡単なフォームならこれでも良いかもしれないが、入力チェックなんてフォームがある限り行うし、毎回毎回上記のようなコードを書くのは美しくない。
共通化したい!と思いドキュメントを読んでみたら、Zend_Filter_Input を使えば実現できそう。
Zend_Filter_Input は宣言型のインターフェイスです。 複数のフィルタやバリデータを関連付け、それをデータの集合に適用し、 そのフィルタやバリデータで処理した後の結果を取得することができます。 デフォルトでは、HTML 出力に適した形式にエスケープされた結果を返します。
http://framework.zend.com/manual/ja/zend.filter.input.html
というわけで、Zend_Filter_Input を使って、バリデーションのルールだけコントローラに書いて、そのルールを登録すれば自動的に入力チェックが掛かるようなコードを書いてみた。
コントローラの親クラス
<?php abstract protected function setRules(); protected function validate() { $this->setRules(); // ルールが記述されてない場合はチェックしないで true を返す if (!is_array($this->_rules)) { return true; } // フィルタは Null $inputs = new Zend_Filter_Input($this->_filters, $this->_rules); $data = $this->_getAllParams(); $ret = $inputs->setOptions(array('breakChainOnFailure' => false)) ->setData($data) ->isValid(); if ($ret === false) { $this->_request->setError('error', $inputs->getMessages()); } return $ret; }
コントローラ
<?php protected function setRules() { require_once 'Zend/Validate/StringLength.php'; require_once 'My/Validate/NotEmpty.php'; $validations = array( 'hoge' => array( new My_Validate_NotEmpty(), new Zend_Validate_StringLength(4, 10), 'messages' => array( 0 => 'hoge は必須です。', 1 => '4文字以上10文字以下で入力して下さい。' ) ) ); $this->_rules = $validations; return $this; }
上記のようなコードをコントローラの親クラス(入門のチュートリアルとかでは Zend_Controller_Action から継承してコントローラを書いてあるけど、自分は Zend_Controller_Action を継承した子クラスをコントローラの親クラスとしてる)に記述した。
で、コントローラの親クラスの preDispatch() で validate() をコールして、false ならエラーを表示するようにした。
これでコントローラ側ではバリデーションのルールのみ記述すれば良い。
やはりこういうオレオレフレームワークもどきを作るには Zend Framework は便利。