Programmer's Reference Guide

標準のバリデーションクラス群

バリデータチェイン

ひとつの値に対して、複数のバリデータを指定した順に適用しなければならないことがよくあります。 以下のコードは、導入 で説明した例を解決するための方法を示すものです。 ユーザ名が 6 文字から 12 文字までの英数字であるかどうかを検証します。

  1. // バリデータチェインを作成し、そこにバリデータを追加します
  2. $validatorChain = new Zend_Validate();
  3. $validatorChain->addValidator(
  4.                     new Zend_Validate_StringLength(array('min' => 6,
  5.                                                          'max' => 12)))
  6.                ->addValidator(new Zend_Validate_Alnum());
  7.  
  8. // ユーザ名を検証します
  9. if ($validatorChain->isValid($username)) {
  10.     // ユーザ名は検証を通過しました
  11. } else {
  12.     // ユーザ名の検証に失敗しました。理由を表示します
  13.     foreach ($validatorChain->getMessages() as $message) {
  14.         echo "$message\n";
  15.     }
  16. }

バリデータは、Zend_Validate に追加した順に適用されます。 上の例では、まずユーザ名の長さが 6 文字から 12 文字までの間であるかどうかを調べます。 その後で、英数字のみであるかどうかだけを調べます。 二番目の検証である「英数字かどうか」は、最初の検証である 「6 文字から 12 文字まで」が成功したかどうかにかかわらず行われます。 つまり、もし両方の検証に失敗した場合は、 getMessages() は両方の検証失敗メッセージを返すことになります。

検証が失敗した時点で、その後の検証を行わずにチェインを抜け出したいこともあるでしょう。 Zend_Validate はそのような使用法もサポートしています。 そのためには、 addValidator() メソッドの二番目のパラメータを使用します。 $breakChainOnFailureTRUE に設定すると、そのバリデータが失敗した時点でチェインを抜け出します。 これにより、後に続く不要な検証や不適切な検証を行わずにすみます。 上の例を次のように書き直すと、長さの検証に失敗した場合は 英数字の検証を行わなくなります。

  1. $validatorChain->addValidator(
  2.                     new Zend_Validate_StringLength(array('min' => 6,
  3.                                                          'max' => 12)),
  4.                     true)
  5.                ->addValidator(new Zend_Validate_Alnum());

Zend_Validate_Interface を実装したオブジェクトなら何でも、 バリデータチェインで使用できます。


標準のバリデーションクラス群

Comments

It seems to me that no precaution is taken to ensure that there are no conflicting error messages (ie. errors that have the same key) between validators. Subsequent validators may overwrite error messages if their key matches an error that is already caught by a previous validator in the chain. The isValid method simply merges the errors from each validator that fails. I guess one needs to be vigilant when chaining validators.
 
$valLoginNotExists = new *_Validate_LoginNotExists();
 $login = $this->createElement('text', 'username', array('class' => 'input'))
                         ->setLabel($this->getView()->translate('Gebruikersnaam'))
                         ->setAllowEmpty(false)
                         ->setValidators(array(
                                 'exists' => array( 
                                     $valLoginNotExists,
                                     'breakChainOnFailure' => true
                                 ),
                                 'wrong' => array(
                                     $valLogin,
                                     'breakChainOnFailure' => true
                                 )    
                             )
                         )

 ->setDecorators(array(array('ViewScript', array('viewScript' => '/form/userForm/_input.phtml'))));
$valLoginNotExists ->setMessage($this->getView()->translate("Login naam niet geldig (min. 6 tekens)"));

Some code to have multiple validators with breaks to use only one validation custom message.

+ Add A Comment

Please do not report issues via comments; use the ZF Issue Tracker.

If you have a JIRA/Crowd account, we suggest you login first before commenting.

  • BBCode is allowed in the comment markup

  • Select a Version

    Languages Available

    Components

    Search the Manual