バリデートをXMLで行う
※ソースは最下部
ZendFrameworkでのバリデーションは普通Zend_Validateを使います。
といっても、分離されているので単独のパッケージですが。
通常では
<?php // バリデータチェインを作成し、そこにバリデータを追加します $validatorChain = new Zend_Validate(); $validatorChain->addValidator(new Zend_Validate_StringLength(6, 12)) ->addValidator(new Zend_Validate_Alnum()); ?>
のように記述していくのですがさすがに毎回それぞれのエラーメッセージを設定したりとめんどくさいです。
なにより送られてくる一つ一つの項目に上記のようなチェックを書くのは正直めんどいです
そこでXMLでZend_Validateを使えるようにしたので紹介。
といっても最低限動くようにチャチャっと作って、後で細かい部分とかコードは調整しようと思っていたので、汚いですが・・・
具体例のほうが分かりやすいと思うので
例として
<?xml version="1.0" encoding="UTF-8"?> <validate> <!-- hoge_id --> <!-- notmust="true"を指定すると空文字列かnullの場合にはバリデートをスキップ --> <hoge_id notmust="true"> <!-- バリデータごとに個別にインバリッドのときのメッセージを指定しないで キーごとにまとめて基本のメッセージを指定することもできます --> <default_invalid_msg></default_invalid_msg> <validate> <!-- break="true"だった場合そのキーの値の中のバリデートのリストで インバリッドだった場合に次以降のバリデートをスキップします ※この場合したのZend_Validate_LessThanのチェック項目 --> <rule break="true"> <!-- バリデートに使うクラス Zend_Validate_Interfaceを実装したクラス --> <validate_class>Zend_Validate_Digits</validate_class> <!-- インバリッドの時のメッセージ --> <invalid_msg>整数で入力してください</invalid_msg> </rule> <rule break="true"> <validate_class>Zend_Validate_LessThan</validate_class> <invalid_msg>1000以下の値を入力してください</invalid_msg> <!-- 引数は最大で3つまで有効 引数は,で区切る 必要になったら無限個数対応するけど・・・めんどいからやめました --> <args>1000</args> </rule> </validate> </hoge_id> </validate>
<?php Zend::loadClass('Toytools_ValidateByXml'); $validator = new Toytools_ValidateByXml( dirname(__FILE__).DIRECTORY_SEPARATOR.'ValidateTest.xml' ); $validator->valid( $_POST ); //$validator->valid( $this->_getAllParams() );//ZendFrameworkの場合はこんな感じ if( !$validator->isValidAll() ){ //全てOK }else{ if( !$validator->isValid('hoge_id') ){ $invalidMsg = $validator->getInvalidMessageList('hoge_id'); //....とか色々 } } ?>
みたいな感じで書けます
- 送られてきたキーが増える場合には
と同階層にキーをタグ名にしたものを増やしていけばOK - デフォルトで用意されているバリデートクラスは十分とはいえないので必要になったらZend_Validate_Interfaceを実装したバリデートクラスを作る
- 個別のインバリッドメッセージがなかったらデフォルトのインバリッドのメッセージを使うとか
まぁある程度の機能は用意されています
※XMLのバリデートははいってません
以下ソース
Toytools_Debugつかってるので必要に応じてはずしてください
Toytools_Debugはこちらid:toytools:20070407
<?php /** * @category Toytools * @package Toytools * @copyright Copyright (c)kaw * @license * @version */ class Toytools_ValidateByXml{ //VALID TYPE KEYS // private $_log;//Toytools_Debug private $_xmlPath; private $_invalidKeyList;//array private $_isValidAll; /* * CONSTRUCT * @param XMLファイルのパス */ function __construct( $xmlPath ){ $this->_log = new Toytools_Debug( __CLASS__ ); $this->_xmlPath = $xmlPath; $this->_invalidKeyList = array(); $this->_isValidAll = true; } /** * XMLを読み込みバリデートを実行します * @param array * @usage * $validator->valid( $this->_getAllParams() ); */ function valid(array $requestList){ if( is_null( $this->_xmlPath ) ){ throw new Exception("XmlPath can't find"); } $xml = simplexml_load_file($this->_xmlPath); foreach( $xml as $validReqItem ){// $requestKey = $validReqItem->getName(); $requestValue = trim($requestList[$requestKey]); $this->_invalidKeyList[$requestKey] = array(); $this->_invalidKeyList[$requestKey]['is_valid'] = true; $this->_invalidKeyList[$requestKey]['invalid_message_list'] = array(); $this->_invalidKeyList[$requestKey]['invalid_class'] = array(); $defaultValidMsg = (string)$validReqItem->default_invalid_msg; $this->_invalidKeyList[$requestKey]['default_invalid_message'] = ( trim($defaultValidMsg) == '' )? null : $defaultValidMsg ; //アトリビュートを展開します $requestKeyAttributes = array(); foreach($validReqItem->attributes() as $a => $b) { $requestKeyAttributes[$a] = $b; } //必須でない宣言のチェック if( strtolower($requestKeyAttributes['notmust']) == 'true' && ( is_null($requestValue) || $requestValue == '' ) ){ continue; } // foreach( $validReqItem->validate->rule as $validItem ){ $validate_class = (string)$validItem->validate_class; $invalid_msg = (string)$validItem->invalid_msg; $args = trim((string)$validItem->args); //アトリビュートを展開します $attributes = array(); foreach($validItem->attributes() as $a => $b) { $attributes[$a] = $b; } Zend::loadClass( $validate_class ); if( $args == '' ){ $valid = new $validate_class();//None }else{ //コンストラクタはcall_user_func_arrayで呼べないのでとりあえず並べとく $args_list = explode( ',' , $args ); switch( count($args_list) ){ case 1: $valid = new $validate_class( $args_list[0] ); break; case 2: $valid = new $validate_class( $args_list[0] , $args_list[1] ); break; case 3: $valid = new $validate_class( $args_list[0] , $args_list[1] , $args_list[2] ); break; default: throw new Exception('ValidateXml ArgsLen is too long'); } } //VALIDATE if( !$valid->isValid( $requestValue ) ){ $this->_log->warn('INVALID CLASS : '.$validate_class , $requestKey); $this->_isValidAll = false; $this->_invalidKeyList[$requestKey]['is_valid'] = false; $this->_addInvalidMessage( $requestKey , $invalid_msg , $validate_class ); if( strtolower($attributes['break']) == 'true' ){ break; } } } } } /** * 全ての項目がValidかどうか * @return boolean */ public function isValidAll(){ return $this->_isValidAll; } /** * 特定キーのものがValidかどうか * @param mixed バリデータのキー * @return boolean */ public function isValid( $requestKey ){ if( is_null($this->_invalidKeyList[$requestKey]['is_valid']) ){ return true;//nullの場合にはバリデートルールのXMLに制約が無いものと見なしTRUEを返却 } return $this->_invalidKeyList[$requestKey]['is_valid']; } /** * バリデータに失敗した箇所のメッセージのリストを取得する * @param mixed バリデータのキー * @param boolean [OPTION]invalidでメッセージが無かった場合にデフォルトメッセージを返却するか * @return null | array * @description * 返却がnullであってもvalidであったとは限りません * validかの判定はisValidを使用してください */ public function getInvalidMessageList( $requestKey , $emptyUseDefault = true ){ $invalidMessageList = $this->_invalidKeyList[$requestKey]['invalid_message_list']; if( is_null( $invalidMessageList ) || count($invalidMessageList) == 0 ){ $defaultInvalidMsg = $this->defaultInvalidMessage( $requestKey ); if( $emptyUseDefault && $this->isValid( $requestKey ) && !is_null( $defaultInvalidMsg ) ){ return array( $defaultInvalidMsg ); } return null; } return $invalidMessageList; } /** * 全てのバリデータに失敗した箇所のメッセージのリスト全てを取得する * Toytools_Viewからコールされます * @return array * @see Toytools_View */ public function getAllInvalidMessageList(){ $return = array(); $invalidMsgList = $this->_invalidKeyList; foreach( $invalidMsgList as $requestKey => $validList ){ //$return[$requestKey] = $validList['invalid_message_list']; $return[$requestKey] = $this->getInvalidMessageList( $requestKey ); } return $return; } /* * バリデータに失敗した箇所のクラス名のリストを取得する * @param mixed バリデータのキー * @return null | array * @description * 返却がnullであってもvalidであったとは限りません * validかの判定はisValidを使用してください */ public function getInvalidClassList( $requestKey ){ $invalidClassList = $this->_invalidKeyList[$requestKey]['invalid_class']; if( is_null( $invalidClassList ) || count($invalidClassList) == 0 ){ return null; } return $invalidClassList; } /** * デフォルトの共通バリデートメッセージを取得する * @param mixed バリデータのキー * @return null | string */ public function defaultInvalidMessage( $requestKey ){ $defaultInvalidMsg = $this->_invalidKeyList[$requestKey]['default_invalid_message']; if( is_null($defaultInvalidMsg) ){ return null; } return $defaultInvalidMsg; } //------------------- PRIVATES ------------------------------------------------------------------ /** * */ private function _addInvalidMessage( $requestKey , $invalidMsg , $validateClass ){ if( is_null($invalidMsg) || $invalidMsg == '' ){ return; } array_push( $this->_invalidKeyList[$requestKey]['invalid_message_list'] , $invalidMsg ); array_push( $this->_invalidKeyList[$requestKey]['invalid_class'] , $validateClass ); } } ?>