第33章 Zend_Validate

目次

33.1. 導入
33.1.1. バリデータとは?
33.1.2. バリデータの基本的な使用法
33.1.3. メッセージのカスタマイズ
33.1.4. 静的メソッド is() の使用法
33.2. バリデータチェイン
33.3. バリデータの書き方
33.4. メールアドレスの検証
33.5. ホスト名の検証

33.1. 導入

Zend_Validate コンポーネントは、一般的に必要となるバリデータを提供します。 シンプルなバリデータチェイン機能も持っており、 ひとつのデータに対して複数のバリデータを指定した順に適用することができます。

33.1.1. バリデータとは?

バリデータは、入力が何らかの要件を満たしているかどうかを調べ、 結果を boolean 値で返します。これは、入力が要件を満たしているかどうかを表します。 入力が要件を満たさなかった場合、バリデータは その入力がどのように要件を満たさなかったのかについての追加情報も提供します。

たとえば、あるウェブアプリケーションでは 「ユーザ名は 6 文字から 12 文字、かつ英数字のみが使用可能」 という要件があるものとします。 このような場合に入力がそれを満たしているかどうかを調べるために バリデータを使用できます。 選択したユーザ名がいずれかひとつあるいは両方の要件を満たしていない場合に、 どちらの条件に反していたのかを知ることができるので便利です。

33.1.2. バリデータの基本的な使用法

ここで考えたバリデータについての定義をもとにして Zend_Validate_Interface が作成されました。これは、 isValid() および getMessages() のふたつのメソッドを定義するものです。 isValid() メソッドは指定した値に対する検証を行います。 値が検証条件を満たしている場合にのみ true を返します。

isValid()false を返した場合、 getMessages() がメッセージの配列を提供します。 ここには検証が失敗した理由が含まれます。

getErrors() メソッドは、 検証が失敗した原因について説明する文字列の配列を返します。 この文字列の内容をもとに、エラーの原因を判断します。 この文字列をもとに判断するのはあくまでもアプリケーションのコードであり、 この内容を直接ユーザに見せることは想定していません。 エラー文字列は各クラスが独自に管理しています。 また、各クラスではそれぞれのエラーを特定するための定数を定義しています。

[注意] 注意

getMessages() および getErrors() が返す情報は、 直近の isValid() コールに関するもののみです。 isValid() をコールすると、それまでに実行された isValid() によるメッセージはすべて消去されます。 なぜなら、通常は、毎回異なる値に対して isValid() をコールするであろうと考えられるからです。

以下の例では、電子メールアドレスの検証方法を説明します。

<?php
require_once 'Zend/Validate/EmailAddress.php';

$validator = new Zend_Validate_EmailAddress();

if ($validator->isValid($email)) {
    //
    // email は妥当な形式です
    //
} else {
    //
    // email は無効な形式です。理由を表示します
    //
    foreach ($validator->getMessages() as $message) {
        echo "$message\n";
    }
}

33.1.3. メッセージのカスタマイズ

バリデータクラスの setMessage() メソッドを使用すると、 検証に失敗した場合に getMessages() が返すメッセージの書式を設定することができます。 最初の引数にはエラーメッセージを文字列で指定します。 このメッセージに特定のトークンを含めると、 バリデータがそれを実際の値に置き換えます。 トークン %value% はすべてのバリデータがサポートしており、 これは isValid() に渡した値に置き換えられます。 その他、バリデータによっていろいろなトークンをサポートしています。 たとえば、Zend_Validate_LessThan では %max% というトークンをサポートしています。

二番目の引数はオプションで、getErrors() メソッドが返すエラー ID に対応する文字列を指定します。 この引数を省略すると、バリデータクラス内で最初に宣言されているメッセージの ID を使用します。 多くのバリデータクラスはエラーメッセージをひとつだけしか持っていないので、 あえてどのメッセージを使用するかを指定する必要はありません。

<?php
require_once 'Zend/Validate/StringLength.php';

$validator = new Zend_Validate_StringLength(8);

$validator->setMessage(
    '文字列 \'%value%\' は短すぎます。最低 %min% 文字以上必要です',
    Zend_Validate_StringLength::TOO_SHORT);

if (!$validator->isValid('word')) {
    $m = $validator->getMessages();
    echo $m[0];

    // 出力は "文字列 'word' は短すぎます。最低 8 文字以上必要です" となります
}

複数のメッセージを setMessages() メソッドで設定することもできます。 その場合の引数は、キー/メッセージ のペアの配列です。

<?php
require_once 'Zend/Validate/StringLength.php';

$validator = new Zend_Validate_StringLength(8, 12);

$validator->setMessages( array(
    Zend_Validate_StringLength::TOO_SHORT => '文字列 \'%value%\' は短すぎます',
    Zend_Validate_StringLength::TOO_LONG  => '文字列 \'%value%\' は長すぎます'
));

より柔軟なエラー報告をしたい場合のために、 バリデータクラスがサポートするメッセージトークンと同じ名前のプロパティを使用することができます。 どのバリデータでも常に使用可能なプロパティは value です。 これは、isValid() の引数として渡した値を返します。 その他のプロパティについては、バリデータクラスによって異なります。

<?php
require_once 'Zend/Validate/StringLength.php';

$validator = new Zend_Validate_StringLength(8, 12);

if (!validator->isValid('word')) {
    echo 'これは、単語として無効です: '
        . $validator->value
        . '。その長さが '
        . $validator->min
        . ' から '
        . $validator->max
        . " までの間ではありません\n";
}

33.1.4. 静的メソッド is() の使用法

指定したバリデータクラスを読み込んでそのインスタンスを作成するというのが面倒ならば、 もうひとつの方法として、静的メソッド Zend_Validate::is() を実行する方法もあります。このメソッドの最初の引数には、 isValid() メソッドに渡す入力値を指定します。 二番目の引数は文字列で、バリデータクラスのベースネーム (Zend_Validate 名前空間における相対的な名前) を指定します。 is() メソッドは自動的にクラスを読み込んでそのインスタンスを作成し、 指定した入力に対して isValid() メソッドを適用します。

<?php
require_once 'Zend/Validate.php';

if (Zend_Validate::is($email, 'EmailAddress')) {
    //
    // email は妥当な形式です
    //
}

バリデータクラスのコンストラクタにオプションを指定する必要がある場合は、 それを配列で渡すことができます。

<?php
require_once 'Zend/Validate.php';

if (Zend_Validate::is($value, 'Between', array(1, 12))) {
    //
    // $value は 1 から 12 までの間です
    //
}

is() は boolean 値を返します。これは isValid() メソッドと同じです。静的メソッド is() を使用した場合は、エラーやメッセージの内容は使用できません。

この静的な使用法は、その場限りの検証には便利です。 ただ、複数の入力に対してバリデータを適用するのなら、 最初の例の方式、つまりバリデータオブジェクトのインスタンスを作成して その isValid() メソッドをコールする方式のほうがより効率的です。

また、Zend_Filter_Input クラスでも、特定の入力データのセットを処理する際に 複数のフィルタやバリデータを必要に応じて実行させる機能も提供しています。 詳細は ??? を参照ください。