バリデーターについて

ZF-Exでは入力した内容をチェックするためのクラスとしてMy_Validateを使用しています。これはZend_Validateのコンポーネント群や独自バリデーションを統合し、単一クラスでバリデーションを実施するためのクラスです。Zend_Validateのリファレンスは下記ページをご覧ください。

http://framework.zend.com/manual/ja/zend.validate.html

基本的な使用方法

 

  • application
    • models
      • Product.php
    • AppModel.php

My_ValidateはAppModel.phpでインスタンス化されています。そのため、AppModelを継承するモデルクラスからメソッドの呼び出しが可能です。

バリデーションのチェック条件はモデルクラス内に記述されています。例えばProduct.phpではクラス内に次のように書かれています。

protected $fields = array(
                        array('key'      => 'category_id',
                              'validate' => array('NotEmpty', array('IdExists', 'categories'))
                        ),
                        array('key'      => 'name',
                              'validate' => array('NotEmpty', array('StringLength', 0, 64))
                        ),
                        array('key'      => 'describe',
                              'validate' => array('NotEmpty', array('StringLength', 0, 1000))
                        ),
                        array('key'      => 'public_flg',
                              'validate' => array('NotEmpty', 'Enum')
                        ),
);

 

appModel::isValid($data)メソッドを呼び出す事で、各モデルの$fieldsメンバ変数内のvalidate設定に応じたバリデーションが行われます。このメソッドはバリデーションで問題があった場合にはfalseを返すので、falseだった場合にはエラーメッセージを取得して個別の処理を行います。

エラーメッセージを取得するメソッドはいくつかあります。どれを使用するかはアプリの設計に応じて判断をお願いします。

  • appModel::getOneErrorMsg(): 1件目のエラーを取得します。エラーメッセージを1件だけ表示したい場合に使用します。
  • appModel::getEachErrorMsg(): 1フィールドあたり1件までのエラーを取得します。各フィールドに対してエラーメッセージを1件ずつ表示したい場合に使用します。
  • appModel::getAllErrorMsg(): 全てのエラーを取得します。各フィールドに対してエラーメッセージが複数あった時、それらを全て表示したい場合に使用します。

 

利用可能なバリデーション条件

My_Validateにより利用可能なバリデーション条件は次の通りです。

  • NotEmpty: 入力必須チェック
  • Int: 整数チェック
  • Kana: カナチェック
  • StringLength: 文字長チェック
  • StringSame: 文字列が同一かチェック
  • Code: コードチェック(半角英数とハイフン、アンダーバーのみ許容)
  • Array: 配列チェック。かつ、値が一つ以上入っている事
  • SingleByte: 半角文字のみかチェック
  • Date: 日付のフォーマットかチェック
  • Tel: 電話番号のフォーマットかチェック
  • Email: メールアドレスのフォーマットかチェック
  • Uri: URLのフォーマットかチェック
  • IdExists: テーブル上にIDが存在するかチェック
  • Enum: 設定されたリスト内の値であるかチェック
  • Unique: ユニークな値であるかチェック
  • FileName: ファイル名として適正かチェック

 

これより個々の条件の設定方法について説明します。なお、一部Zend_Validateのクラスを利用したラッパクラスもありますが、NotEmpty以外は空欄入力を許可するようにしてあります。そのため、空欄を不許可とする場合には必ずNotEmptyを指定するようにお願いします。

NotEmpty

空欄でない事をチェックします。引数は不要です。

Int

整数である事をチェックします。他の引数は不要です。

Kana

カナ文字である事をチェックします。他の引数は不要です。

StringLength

文字長が指定の範囲に収まる事をチェックします。マルチバイト文字とシングルバイト文字の区別は行わず、いずれも同様の1文字として計算します。第二引数が下限、第三引数が上限になります。

StringSame

文字列が同一である事をチェックします。パスワード入力と入力確認等で使用する事を想定しています。第二引数が固定の文字列、第三引数がキー名になります。第三引数を入力している場合、そのキー名を持つ入力データを取得し、文字列の照合を行います。第三引数が空欄で第二引数を入力している場合、その文字列と照合を行います。

Code

半角英数、ハイフン、アンダーバーからなる文字列である事をチェックします。他の引数は不要です。

Array

配列であり、かつ空欄でない事をチェックします。チェックボックスにより複数の項目を入力する時に使用する事を想定しています。他の引数は不要です。

SingleByte

シングルバイトのみの文字列である事をチェックします。他の引数は不要です。

Date

日付形式の文字列である事をチェックします。他の引数は不要です。

Tel

電話番号形式の文字列である事をチェックします。ここでは厳密に日本の電話番号フォーマットではなく、次の条件を満たせば電話番号の形式であると判断します。他の引数は不要です。

  1. 半角数字とハイフンのみからなる
  2. ハイフンは2回以上連続しない
  3. 文字列の最初と最後は半角数字である

 

Email

メール形式の文字列である事をチェックします。他の引数は不要です。

Uri

Uri形式の文字列である事をチェックします。他の引数は不要です。

IdExists

指定するテーブルにidが存在するかチェックします。外部キーが設定されている項目のチェックで使用する事を想定しています。第二引数が対象とするテーブル名、第三引数がフィールド名なります。第三引数を省略した場合は主キーの「id」を使用します。

論理削除された行を検索対象とするかはModelで論理削除を使うかどうかの設定と同じになります。変更したい時はModelのメソッドappModel::addUseDeleteDate($key, $validate_name, $useDeleteDate)を用いる事で後から変更します。$keyには対象のフィールド名、$validate_nameにはIdExistsを指定します。

Enum

設定されたリスト内にidが存在するかチェックします。IdExistsと似ていますが、IdExistsは対象のテーブルにその値を持つかチェックするのに対して、Enumは配列をセットし、その中に値が含まれているかをチェックします。商品に対するカテゴリなど、idのリストが頻繁に変更される場合はIDExists、ステータス情報など変更がほとんどない場合はEnumという使い分けを想定しています。

Enumを使用する場合、対象となるリストの設定を行う必要があります。ModelのメソッドAppModel::addEnumList($key, $value)によりリストが設定されます。リストの値が静的であればModelクラスのコンストラスタで呼び出すとよいかと思います。

Unique

入力した文字列がそのテーブル中でユニークなものであるかチェックします。主キー以外で重複してはならないフィールドに対して設定を行います。第二引数がテーブル名、第三引数がフィールド名になります。

そのテーブルに対して行う処理が新規追加の場合にはユニークとなる文字列はテーブルに入っていないかチェックすればいいですが、更新処理の場合には自分自身の項目は除外する必要があります。除外する条件を追加するにはModelのメソッドappModel::addUniqueCond($key, $column, $value, $equal = false)を使用します。例えば、あるモデルのフィールド「code」を自分自身を除外してUniqueか判定する場合、コントローラ中に次のように記述します。

$this->_model->addUniqueCond('code', 'id', $id);

論理削除された行を検索対象とするかはModelで論理削除を使うかどうかの設定と同じになります。変更したい時はModelのメソッドappModel::addUseDeleteDate($key, $validate_name, $useDeleteDate)を用いる事で後から変更します。$keyには対象のフィールド名、$validate_nameにはUniqueを指定します。

FileName

ファイル名として適切であるかチェックします。次の条件を満たせば適切であると判断します。他の引数は不要です。

  1. ウインドウズでファイル名に使用不可な文字列(\ < > : " / \ | ? *)が含まれていない
  2. 文字列の末尾が拡張子である。最後の.(ピリオド)から先は半角英数のみからなる

 

表示メッセージの変更方法

表示メッセージは次のファイルにより管理しています。ここに書かれているvalidateのエラーメッセージを編集する事でメッセージが変更されます。

  • application
    • messages
      • jp
        • code.ini

この他、規定のメッセージの他に独自のエラーメッセージを設定する事も可能です。ModelのメソッドappModel::addAdditionalErrorMsg($field, $msg, $code = '')appModel::addAdditionalErrorMessageId($field, $messageid, $code = '')を使用する事で独自のエラーメッセージを設定可能です。例えば、あるモデルのフィールド「code」の空欄チェックエラー「isEmpty」に新しいメッセージを設定する場合、コントローラ中に次のように記述します。

$this->_model->addAdditionalErrorMsg('code', 'New Error Message', 'isEmpty');
$this->_model->addAdditionalErrorMessageId('code', 'New Error Message id', 'isEmpty');

この2つのメソッドの差異はエラーが発生した時にそのメッセージを直接呼び出すか、バリデータから呼び出すかの違いにあります。addAdditionalErrorMessageIdはバリデータから呼び出すため、フィールド名などの差し込み項目があれば自動的に変換が実行されます。また、addAdditionalErrorMessageIdはトランスレータを経由するため、トランスレータに登録されていれば自動的に翻訳されます。

第三引数ではどのエラーコードに対する独自メッセージであるかを指定します。指定がない場合はデフォルトのエラーメッセージと設定され、そのフィールドの入力チェックでエラーが発生した時に常にそのメッセージが返ってくるようになります。

独自バリデーションの追加方法

従来のバリデーションの他、独自のバリデーションが必要になった時は、新しいバリデーションを作成可能です。詳細についてはバリデーション条件の追加についてを参照下さい。

バリデーションの設定変更方法

処理のパターンにより、バリデーションの条件を変更する場合はModelのメソッドにより変更可能です。関連するModelメソッドはappModel::getValidate($key)appModel::addValidate($key, $validate)appModel::setValidate($key, $validate)です。

現在のバリデーション設定を取得するにはappModel::getValidate($key)を使用します。

$validate = $this->_model->getValidate($key);

現在のバリデーションの最後に新しいバリデーションを追加するにはappModel::addValidate($key, $validate)を使用します。なお、追加するバリデーション設定は1項目となります。

$this->_model->addValidate($key, $validate);

現在のバリデーションを新しいバリデーションを置き換えるにはappModel::setValidate($key, $validate)を使用します。なお、追加するバリデーション設定は複数項目となるため、$validateはarrayとなります。

$this->_model->setValidate($key, $validate);