[GENERIC] Zend_Translate:
[zend.git] / documentation / manual / ja / module_specs / Zend_Validate-WritingValidators.xml
blob97871ee2563dd045f3321a408b805002483f180e
1 <?xml version="1.0" encoding="UTF-8"?>
2 <!-- Reviewed: no -->
3 <!-- EN-Revision: 20799 -->
4 <sect1 id="zend.validate.writing_validators">
6     <title>バリデータの書き方</title>
8     <para>
9         <classname>Zend_Validate</classname> には、よく使うバリデータ群が付属しています。しかし、
10         特定の目的のために使用する独自のバリデータを書くことは避けられないでしょう。
11         ここでは、独自のバリデータを書く方法について説明します。
12     </para>
14     <para>
15         <classname>Zend_Validate_Interface</classname> では、2つのメソッド <methodname>isValid()</methodname>、
16         および <methodname>getMessages()</methodname>
17         を定義しています。これらを自分のクラスで実装して
18         独自のバリデーションオブジェクトを作成します。
19         <classname>Zend_Validate_Interface</classname> を実装したクラスは、
20         <methodname>Zend_Validate::addValidator()</methodname>
21         でバリデータチェインに追加できます。
22         このオブジェクトは
23         <link linkend="zend.filter.input"><classname>Zend_Filter_Input</classname></link>
24         でも使用します。
25     </para>
27     <para>
28         上の <classname>Zend_Validate_Interface</classname> についての説明からも推測できるように、
29         Zend Framework が提供しているバリデーションクラスの返り値は、
30         検証に成功したか失敗したかを表す boolean 値となります。また、<emphasis>なぜ</emphasis>
31         検証が失敗したのかについての情報も提供します。この理由がわかると、
32         アプリケーション側で何かと便利です。たとえば、ユーザビリティ改善のための統計情報として利用することなどができます。 
33     </para>
35     <para>
36         基本的な検証失敗メッセージ機能を実装しているのが <classname>Zend_Validate_Abstract</classname> です。
37         バリデーションクラスを作成する際にこの機能を組み込むには、
38         <classname>Zend_Validate_Abstract</classname> を継承します。
39         継承したクラス内で <methodname>isValid()</methodname> メソッドのロジックを実装し、
40         発生しうる失敗の形式に対応したメッセージ変数とメッセージテンプレートを定義します。
41         検証に失敗した場合には <methodname>isValid()</methodname> は <constant>FALSE</constant>
42         を返さなければなりません。検証を通過した場合は、<methodname>isValid()</methodname>
43         は <constant>TRUE</constant> を返さなければなりません。
44     </para>
46     <para>
47         一般に、<methodname>isValid()</methodname> メソッドは例外をスローすべきではありません。
48         例外をスローするのは、入力値が妥当かそうでないかの判断ができない場合のみとします。
49         例外をスローすることになる場面としては、たとえばファイルのオープンに失敗したり
50         <acronym>LDAP</acronym> サーバとの接続に失敗したり、データベースとの接続に失敗したり
51         といった原因で入力値が正しいのかどうかが判断できない場合が考えられます。
52     </para>
54     <example id="zend.validate.writing_validators.example.simple">
56         <title>単純なバリデーションクラスの作成</title>
58         <para>
59             次の例は、非常に単純なバリデータの書き方を説明するものです。
60             ここで定義している検証規則は非常に単純で、入力値が浮動小数点値かどうかのみを調べています。
61         </para>
63         <programlisting language="php"><![CDATA[
64 class MyValid_Float extends Zend_Validate_Abstract
66     const FLOAT = 'float';
68     protected $_messageTemplates = array(
69         self::FLOAT => "'%value%' は浮動小数点値ではありません"
70     );
72     public function isValid($value)
73     {
74         $this->_setValue($value);
76         if (!is_float($value)) {
77             $this->_error();
78             return false;
79         }
81         return true;
82     }
84 ]]></programlisting>
86         <para>
87             このクラス内には、検証が失敗したときのメッセージ用のテンプレートがひとつ定義されており、
88             その中では組み込みのマジックパラメータ <emphasis>%value%</emphasis> を使用しています。
89             <methodname>_setValue()</methodname> のコールによって、検証した値をこのメッセージに自動的に格納します。
90             これにより、検証に失敗したときに、この値をメッセージに含められるようになります。
91             <methodname>_error()</methodname> のコールによって、検証に失敗した原因を取得します。
92             このクラスでは失敗時のメッセージをひとつしか用意していないので、
93             <methodname>_error()</methodname> でメッセージテンプレートの名前を指定する必要はありません。
94         </para>
96     </example>
98     <example id="zend.validate.writing_validators.example.conditions.dependent">
100         <title>依存条件を伴うバリデーションクラスの作成</title>
102         <para>
103             次の例は、複数の検証規則を組み合わせた複雑なものとなります。
104             ここでは、まず入力値が数値であること、そして指定した最小値と最大値の間にあることを調べます。
105             以下のいずれかが発生したときに、検証は失敗します。
106         </para>
108         <itemizedlist>
109             <listitem>
110                 <para>入力値が数値ではない</para>
111             </listitem>
113             <listitem>
114                 <para>入力値が最小値より小さい</para>
115             </listitem>
117             <listitem>
118                 <para>入力値が最大値より大きい</para>
119             </listitem>
120         </itemizedlist>
122         <para>
123             これらの原因に応じて、クラス内でメッセージへの変換が行われます。
124         </para>
126         <programlisting language="php"><![CDATA[
127 class MyValid_NumericBetween extends Zend_Validate_Abstract
129     const MSG_NUMERIC = 'msgNumeric';
130     const MSG_MINIMUM = 'msgMinimum';
131     const MSG_MAXIMUM = 'msgMaximum';
133     public $minimum = 0;
134     public $maximum = 100;
136     protected $_messageVariables = array(
137         'min' => 'minimum',
138         'max' => 'maximum'
139     );
141     protected $_messageTemplates = array(
142         self::MSG_NUMERIC => "'%value%' は数値ではありません",
143         self::MSG_MINIMUM => "'%value%' は '%min%' 以上でなければなりません",
144         self::MSG_MAXIMUM => "'%value%' は '%max%' 以下でなければなりません"
145     );
147     public function isValid($value)
148     {
149         $this->_setValue($value);
151         if (!is_numeric($value)) {
152             $this->_error(self::MSG_NUMERIC);
153             return false;
154         }
156         if ($value < $this->minimum) {
157             $this->_error(self::MSG_MINIMUM);
158             return false;
159         }
161         if ($value > $this->maximum) {
162             $this->_error(self::MSG_MAXIMUM);
163             return false;
164         }
166         return true;
167     }
169 ]]></programlisting>
171         <para>
172             パブリックプロパティ <code>$minimum</code> および <code>$maximum</code>
173             でそれぞれ最小値と最大値を定義し、値がこの間にあった場合に検証が成功したことにしています。
174             このクラスではまた、それぞれのパブリックプロパティに対応するふたつのメッセージ変数を定義しています。
175             そしてメッセージテンプレートの中で <property>value</property> と同様に使えるマジックパラメータとして
176             <property>min</property> および <property>max</property> も用意しています。
177         </para>
179         <para>
180             <methodname>isValid()</methodname> での妥当性チェックのいずれかが失敗すると、
181             適切なメッセージを準備して即時に <constant>FALSE</constant> を返すことに注意しましょう。
182             つまり、これらの検証は、その並び順に依存します。
183             どれかひとつのチェックが失敗すると、それ以降の検証規則を確認する必要はなくなるからです。
184             しかし、時にはこのような処理が不要な場合もあります。
185             次の例は、個々の検証規則を独立させたクラスを書く方法を示すものです。
186             このバリデーションオブジェクトは、検証に失敗したときに複数の理由を返すことがあります。
187         </para>
189     </example>
191     <example id="zend.validate.writing_validators.example.conditions.independent">
193         <title>個々に独立した条件による検証を行い、失敗時に複数の原因を返す</title>
195         <para>
196             パスワードの強度を確認するバリデーションクラスを書くことを考えてみましょう。
197             ユーザに対して、安全なユーザアカウントを発行するために
198             ある条件を満たしたパスワードを設定してもらう際に使用するものです。
199             パスワードの条件としては、次のようなものを前提とします。
200         </para>
202         <itemizedlist>
203             <listitem><para>最低 8 文字以上であること</para></listitem>
204             <listitem><para>最低ひとつの大文字を含むこと</para></listitem>
205             <listitem><para>最低ひとつの小文字を含むこと</para></listitem>
206             <listitem><para>最低ひとつの数字を含むこと</para></listitem>
207         </itemizedlist>
209         <para>
210             この検証規則を実装したクラスは、次のようになります。
211         </para>
213         <programlisting language="php"><![CDATA[
214 class MyValid_PasswordStrength extends Zend_Validate_Abstract
216     const LENGTH = 'length';
217     const UPPER  = 'upper';
218     const LOWER  = 'lower';
219     const DIGIT  = 'digit';
221     protected $_messageTemplates = array(
222         self::LENGTH => "'%value%' は少なくとも 8 文字以上でなければなりません",
223         self::UPPER  => "'%value%' には最低ひとつの大文字が必要です",
224         self::LOWER  => "'%value%' には最低ひとつの小文字が必要です",
225         self::DIGIT  => "'%value%' には最低ひとつの数字が必要です"
226     );
228     public function isValid($value)
229     {
230         $this->_setValue($value);
232         $isValid = true;
234         if (strlen($value) < 8) {
235             $this->_error(self::LENGTH);
236             $isValid = false;
237         }
239         if (!preg_match('/[A-Z]/', $value)) {
240             $this->_error(self::UPPER);
241             $isValid = false;
242         }
244         if (!preg_match('/[a-z]/', $value)) {
245             $this->_error(self::LOWER);
246             $isValid = false;
247         }
249         if (!preg_match('/\d/', $value)) {
250             $this->_error(self::DIGIT);
251             $isValid = false;
252         }
254         return $isValid;
255     }
257 ]]></programlisting>
259         <para>
260             <methodname>isValid()</methodname> では四つのチェックを行っていますが、
261             チェックに失敗してもその場では <constant>FALSE</constant> を返していないことに注目しましょう。
262             これにより、入力されたパスワードが満たしていない条件を <emphasis>すべて</emphasis>
263             示すことができるようになります。たとえば、パスワードとして入力された値が
264             "#$%" だったとすると、<methodname>isValid()</methodname>
265             は四つのメッセージをすべて作成し、後で <methodname>getMessages()</methodname>
266             をコールした際にすべて取得できるようになります。
267         </para>
269     </example>
271 </sect1>
272 <!--
273 vim:se ts=4 sw=4 et: