[ZF-10089] Zend_Log
[zend.git] / documentation / manual / ru / module_specs / Zend_Validate-WritingValidators.xml
bloba84e8118964b02d5be57dd92acd50098d785e0ae
1 <?xml version="1.0" encoding="UTF-8"?>
2 <!-- Reviewed: no -->
3 <sect1 id="zend.validate.writing_validators">
5     <title>Написание валидаторов</title>
7     <para>
8         <classname>Zend_Validate</classname> предоставляет набор наиболее
9         часто используемых валидаторов, но разработчики часто сталкиваются
10         с такими ситуациями, когда требуется написание своих валидаторов.
11         В этом разделе описан процесс написания своих валидаторов.
12     </para>
14     <para>
15         <classname>Zend_Validate_Interface</classname> определяет три метода:
16         <code>isValid()</code>, <code>getMessages()</code> и
17         <code>getErrors()</code>, они должны
18         реализовываться в ваших классах валидации.
19         Объект, реализующий данный интерфейс, может быть добавлен в цепочку
20         валидаторов через метод <code>Zend_Validate::addValidator()</code>,
21         также такие объекты могут использоваться с классом
22         <link linkend="zend.filter.input"><classname>Zend_Filter_Input</classname></link>.
23     </para>
25     <para>
26         Как вы наверное уже поняли из приведенного выше описания
27         интерфейса <classname>Zend_Validate_Interface</classname>,
28         классы валидации, предоставляемые Zend Framework, возвращают
29         булево значение, означающее успех/неуспех валидации.
30         Они также предоставляют информацию о том
31         <emphasis>почему</emphasis> переданное значение не прошло
32         валидацию. Возможность узнать причину того, почему значение не проходит
33         валидацию, может быть полезна для различных целей, как, например,
34         создание статистики для анализа удобства использования приложения.
35     </para>
37     <para>
38         Базовый функционал для сообщений об ошибке валидации реализован в
39         классе <classname>Zend_Validate_Abstract</classname>.
40         Для того, чтобы использовать этот функционал при создании класса
41         валидации, просто наследуйте свой класс от
42         <classname>Zend_Validate_Abstract</classname>.
43         В классе-наследнике вы можете реализовать логику метода
44         <code>isValid()</code>, а также определить шаблоны и переменные
45         сообщений, которые соответствуют различным типам ошибок валидации.
46         Если значение не проходит проверку, то <code>isValid()</code> должен
47         возвращать <constant>FALSE</constant>. Если значение проходит проверку, то
48         <code>isValid()</code> должен возвращать <constant>TRUE</constant>.
49     </para>
51     <para>
52         Обычно метод <code>isValid()</code> не должен бросать никаких
53         исключений, за исключением тех ситуаций, когда невозможно определить,
54         является ли валидным входное значение или нет.
55         Например, бросок исключения уместен в случае,
56         когда невозможно открыть файл (недоступен сервер LDAP,
57         нет соединения с базой данных), и процесс валидации не может быть
58         продолжен.
59     </para>
61     <example id="zend.validate.writing_validators.example.simple">
63         <title>Создание простого класса валидации</title>
65         <para>
66             Следующий пример демонстрирует создание простейшего валидатора.
67             В данном случае правила валидации просты - входное значение
68             должно иметь тип <code>float</code>.
70             <programlisting language="php"><![CDATA[
71 class MyValid_Float extends Zend_Validate_Abstract
73     const FLOAT = 'float';
75     protected $_messageTemplates = array(
76         self::FLOAT => "'%value%' не является числом с плавающей точкой"
77     );
79     public function isValid($value)
80     {
81         $this->_setValue($value);
83         if (!is_float($value)) {
84             $this->_error();
85             return false;
86         }
88         return true;
89     }
91 ]]></programlisting>
93             В данном классе определен шаблон для единственного сообщения
94             об ошибке валидации, который включает в себя встроенный "магический"
95             параметр <code>%value%</code>.
96             Вызов <code>_setValue()</code> подготавливает объект к подстановке
97             проверяемого значения в сообщение об ошибке.
98             Вызов <code>_error()</code> устанавливает причину ошибки валидации.
99             Поскольку в этом классе только одно сообщение об ошибке,
100             то нет необходимости передавать методу <code>_error()</code>
101             имя шаблона сообщения об ошибке.
102         </para>
104     </example>
106     <example id="zend.validate.writing_validators.example.conditions.dependent">
108         <title>Написание классов валидации с подчиненными условиями</title>
110         <para>
111             Следующий пример демонстрирует более сложный набор правил валидации,
112             где требуется, чтобы входное значение было числом, находящимся
113             в диапазоне между минимальным и максимальным значениями.
114             Значение может не пройти валидацию по одной из следующих причин:
116             <itemizedlist>
117                 <listitem>
118                     <para>Значение не является числом.</para>
119                 </listitem>
120                 <listitem>
121                     <para>Значение меньше минимально допустимого.</para>
122                 </listitem>
123                 <listitem>
124                     <para>Значение больше максимально допустимого.</para>
125                 </listitem>
126             </itemizedlist>
127         </para>
129         <para>
130             Эти возможные причины переводятся в определения в классе:
132             <programlisting language="php"><![CDATA[
133 class MyValid_NumericBetween extends Zend_Validate_Abstract
135     const MSG_NUMERIC = 'msgNumeric';
136     const MSG_MINIMUM = 'msgMinimum';
137     const MSG_MAXIMUM = 'msgMaximum';
139     public $minimum = 0;
140     public $maximum = 100;
142     protected $_messageVariables = array(
143         'min' => 'minimum',
144         'max' => 'maximum'
145     );
147     protected $_messageTemplates = array(
148         self::MSG_NUMERIC => "'%value%' не является числом",
149         self::MSG_MINIMUM => "'%value%' должен быть не меньше '%min%'",
150         self::MSG_MAXIMUM => "'%value%' должен быть не больше '%max%'"
151     );
153     public function isValid($value)
154     {
155         $this->_setValue($value);
157         if (!is_numeric($value)) {
158             $this->_error(self::MSG_NUMERIC);
159             return false;
160         }
162         if ($value < $this->minimum) {
163             $this->_error(self::MSG_MINIMUM);
164             return false;
165         }
167         if ($value > $this->maximum) {
168             $this->_error(self::MSG_MAXIMUM);
169             return false;
170         }
172         return true;
173     }
175 ]]></programlisting>
177             Открытые свойства <varname>$minimum</varname> и <varname>$maximum</varname>
178             были созданы для установки нижней и верхней границ диапазона
179             соответственно.
180             В классе также определены две переменные сообщений, которые
181             соответствуют этим открытым свойствам и позволяют использовать
182             <code>min</code> и <code>max</code>
183             в качестве магических параметров в шаблонах сообщений, так же,
184             как и <code>value</code>.
185         </para>
187         <para>
188             Обратите вмимание, что если какая-либо из проверок в методе
189             <code>isValid()</code> не была пройдена, то подготавливается
190             соответствующее сообщение и метод сразу же возвращает
191             <constant>FALSE</constant>.
192             Таким образом, эти правила валидации являются
193             последовательно-зависимыми. Это значит, что если одна из проверок не
194             была пройден, то нет необходимости производить последующие проверки.
195             Но это не обязательный случай, в следующем примере показан
196             класс с независимыми правилами валидации, где объект
197             валидации может возвращать несколько причин, по которым валидация
198             не была пройдена.
199         </para>
201     </example>
203     <example id="zend.validate.writing_validators.example.conditions.independent">
205         <title>Валидация с независимыми условиями и возвратом нескольких причин непрохождения валидации</title>
207         <para>
208             Рассмотрим написание класса валидации для обеспечения стойкости
209             пароля, где от пользователя требуется
210             выбрать пароль, который соответствует определенным критериям в целях
211             защиты пользовательского аккаунта.
212             Предположим, что критерии безопасности требуют, чтобы пароль:
214             <itemizedlist>
215                 <listitem>
216                     <para>был длиной как минимум 8 символов,</para>
217                 </listitem>
218                 <listitem>
219                     <para>содержал как минимум одну букву в верхнем регистре,</para>
220                 </listitem>
221                 <listitem>
222                     <para>содержал как минимум одну букву в нижнем регистре,</para>
223                 </listitem>
224                 <listitem>
225                     <para>содержал как минимум один цифровой символ.</para>
226                 </listitem>
227             </itemizedlist>
228         </para>
230         <para>
231             Следующий класс реализует эти критерии валидации:
233             <programlisting language="php"><![CDATA[
234 class MyValid_PasswordStrength extends Zend_Validate_Abstract
236     const LENGTH = 'length';
237     const UPPER  = 'upper';
238     const LOWER  = 'lower';
239     const DIGIT  = 'digit';
241     protected $_messageTemplates = array(
242         self::LENGTH => "'%value%' должен быть длиной как минимум 8 символов",
243         self::UPPER  => "'%value%' должен содержать как минимум одну букву в верхнем регистре",
244         self::LOWER  => "'%value%' должен содержать как минимум одну букву в нижнем регистре",
245         self::DIGIT  => "'%value%' должен содержать как минимум один цифровой символ"
246     );
248     public function isValid($value)
249     {
250         $this->_setValue($value);
252         $isValid = true;
254         if (strlen($value) < 8) {
255             $this->_error(self::LENGTH);
256             $isValid = false;
257         }
259         if (!preg_match('/[A-Z]/', $value)) {
260             $this->_error(self::UPPER);
261             $isValid = false;
262         }
264         if (!preg_match('/[a-z]/', $value)) {
265             $this->_error(self::LOWER);
266             $isValid = false;
267         }
269         if (!preg_match('/\d/', $value)) {
270             $this->_error(self::DIGIT);
271             $isValid = false;
272         }
274         return $isValid;
275     }
277 ]]></programlisting>
279             Обратите внимание, что эти четыре проверки в методе
280             <code>isValid()</code> не сразу же возвращают <constant>FALSE</constant>.
281             Это позволяет классу валидации предоставлять
282             <emphasis>все</emphasis> причины того, почему
283             введенный пароль не отвечает требованиям валидации.
284             Если, например, пользователь введет строку "<code>#$%</code>"
285             в качестве пароля, то после <code>isValid()</code>
286             вызов <code>getMessages()</code> вернет все четыре
287             сообщения ошибки валидации.
288         </para>
290     </example>
292 </sect1>
293 <!--
294 vim:se ts=4 sw=4 et: