1 <sect1 id="zend.form.quickstart">
2 <title>Zend_Form - Быстрый старт</title>
5 Данное руководство охватывает основы создания форм,
6 проверки корректности данных и визуализиции с использованием
7 <code>Zend_Form</code>.
10 <sect2 id="zend.form.quickstart.create">
11 <title>Создание объекта формы</title>
14 Объекты форм создаются через простое инстанцирование
15 <code>Zend_Form</code>:
18 <programlisting language="php"><![CDATA[
19 $form = new Zend_Form;
24 Для более сложных случаев использования вы можете создавать
25 подклассы <code>Zend_Form</code>, но простые формы вы можете
26 создавать, используя объект <code>Zend_Form</code>.
30 Если вы хотите указать атрибуты <code>action</code> и
31 <code>method</code> (что во всех случаях является хорошей идеей), то
32 можете сделать это с использованием аксессоров
33 <code>setAction()</code> и <code>setMethod()</code>:
36 <programlisting language="php"><![CDATA[
37 $form->setAction('/resource/process')
43 Приведенный выше код устанавливает значение атрибута
44 <code>action</code> равным "/resource/process" и указывает способ
45 отправки данных - HTTP POST. Эти атрибуты будут выведены после
46 окончательного рендеринга формы.
50 Вы можете установить дополнительные HTML-атрибуты для тега
51 <code><form></code>, используя методы <code>setAttrib()</code>
52 и <code>setAttribs()</code>. Например, если нужно установить
53 идентификатор элемента формы, то установите атрибут "id":
56 <programlisting language="php"><![CDATA[
57 $form->setAttrib('id', 'login');
62 <sect2 id="zend.form.quickstart.elements">
63 <title>Добавление элементов в форму</title>
66 Форма без элементов бесмысленна. <code>Zend_Form</code>
67 поставляется с некоторым начальным набором элементов, которые
68 отвечают за рендеринг XHTML-кода с использованием помощников
69 <code>Zend_View</code>. В этот список входят элементы:
78 checkbox (флажок опций, или несколько флажков опций
83 hidden (спрятанное поле)
103 select (выпадающий список - как обычный, так multi-select)
107 submit (кнопка отправки)
111 text (текстовое поле)
115 textarea (текстовая область)
120 Есть два способа добавления элементов в форму - вы можете
121 инстанцировать нужные элементы и передавать их объекту формы, или
122 передавать только тип элемента, в этом случае <code>Zend_Form</code>
123 инстанцирует соответствующий объект за вас.
130 <programlisting language="php"><![CDATA[
131 // Инстанцирование элемента и его передача объекту формы:
132 $form->addElement(new Zend_Form_Element_Text('username'));
134 // Передача типа элемента объекту формы
135 $form->addElement('text', 'username');
140 По умолчанию элементы не имеют никаких валидаторов или фильтров. Это
141 означает, что вам нужно установить к своим элементам, как минимум,
142 валидаторы, и, возможно, фильтры. Вы можете делать это (a) до
143 передачи элементов в форму, (b) через опции конфигурирования,
144 которые передаются при создании элемента через
145 <code>Zend_Form</code>, или (с) путем извлечения элементов формы из
146 объекта формы и их конфигурирования.
150 Сначала рассмотрим создание валидаторов для конкретного объекта
151 элемента. Вы можете передавать объекты <code>Zend_Validate_*</code>
152 или имена валидаторов:
155 <programlisting language="php"><![CDATA[
156 $username = new Zend_Form_Element_Text('username');
158 // Передача объекта Zend_Validate_*:
159 $username->addValidator(new Zend_Validate_Alnum());
161 // Передача имени валидатора:
162 $username->addValidator('alnum');
166 В случае использования второго варианта, если валидатор принимает
167 аргументы конструктора, то вы можете передавать их через массив как
171 <programlisting language="php"><![CDATA[
173 $username->addValidator('regex', false, array('/^[a-z]/i'));
178 (Второй параметр используется для указания того, должен ли валидатор
179 в том случае, если данные не прошли проверку, прерывать дальнейшую
180 проверку в цепочке валидаторов; по умолчанию он равен false.)
184 Вы можете также указать элемент как обязательный для заполнения. Это
185 может быть сделано как с помощью аксессора, так и путем
186 передачи определенной опции при создании элемента. В первом случае:
189 <programlisting language="php"><![CDATA[
190 // Указание того, что элемент обязателен для заполнения:
191 $username->setRequired(true);
196 Если элемент обязателен для заполнения, то в начало цепочки
197 валидаторов добавляется валидатор 'NotEmpty', который проверяет,
198 имеет ли элемент значение.
202 Фильтры регистрируются в основном так же, как и валидаторы. Для
203 демонстрации добавим фильтр для приведения значения к
207 <programlisting language="php"><![CDATA[
208 $username->addFilter('StringToLower');
213 Таким образом, окончательно установка элемента получится
214 такой, как показано ниже:
217 <programlisting language="php"><![CDATA[
218 $username->addValidator('alnum')
219 ->addValidator('regex', false, array('/^[a-z]/'))
221 ->addFilter('StringToLower');
223 // или в более компактной форме:
224 $username->addValidators(array('alnum',
225 array('regex', false, '/^[a-z]/i')
228 ->addFilters(array('StringToLower'));
233 Выполнение этих действий для каждого элемента по отдельности может
234 показаться несколько утомительным. Попробуем вариант (b) из
235 перечисленных выше. Когда мы создаем новый элемент, используя
236 <code>Zend_Form::addElement()</code> в качестве фабрики, то можем
237 опционально передавать опции конфигурирования. Они могут включать в
238 себя валидаторы и фильтры для использования. Таким образом, чтобы
239 неявным образом сделать все это, попробуйте следующее:
242 <programlisting language="php"><![CDATA[
243 $form->addElement('text', 'username', array(
244 'validators' => array(
246 array('regex', false, '/^[a-z]/i')
249 'filters' => array('StringToLower'),
255 Если вы обнаружили, что настраиваете элементы, используя одни и те
256 же опции во многих местах, то можете создать подкласс
257 <code>Zend_Form_Element</code> и использовать его вместо выполнения
258 этих процедур; это может избавить от лишней работы по набору кода.
262 <sect2 id="zend.form.quickstart.render">
263 <title>Визуализация формы</title>
266 Визуализация формы производится легко. Большинство элементов
267 использует помощника <code>Zend_View</code> для генерации вывода и
268 поэтому нуждаются в объекте вида для выполнения рендеринга. Есть
269 два способа запустить рендеринг: использовать метод формы render()
270 или просто вывести форму с помощью echo.
273 <programlisting language="php"><![CDATA[
274 // Явный вызов render() с передачей объекта вида:
275 echo $form->render($view);
277 // Предполагается, что объект вида уже был установлен ранее через setView():
283 По умолчанию <code>Zend_Form</code> будет пытаться использовать
284 объект вида, инициализированный в <code>ViewRenderer</code>, это
285 означает, что вам не нужно будет вручную устанавливать объект вида
286 при использовании MVC Zend Framework-а. Код для визуализации формы
287 в скрипте вида весьма прост:
290 <programlisting language="php"><![CDATA[
291 <?php echo $this->form ?>
296 Внутри себя <code>Zend_Form</code> использует "декораторы" для
297 выполнения визуализации. Эти декораторы могут замещать содержимое
298 переданного элемента, производить добавления в его начало и конец,
299 производить наблюдение за ним. В результате вы можете комбинировать
300 несколько декораторов для достижения нужного эффекта. По умолчанию
301 в <code>Zend_Form_Element</code> используется четыре декоратора
302 для получения нужного вывода; их установка выглядит приблизительно
306 <programlisting language="php"><![CDATA[
307 $element->addDecorators(array(
310 array('HtmlTag', array('tag' => 'dd')),
311 array('Label', array('tag' => 'dt')),
317 Код выше создает вывод наподобие следующего:
320 <programlisting language="html"><![CDATA[
321 <dt><label for="username" class="required">Username</dt>
323 <input type="text" name="username" value="123-abc" />
325 <li>'123-abc' has not only alphabetic and digit characters</li>
326 <li>'123-abc' does not match against pattern '/^[a-z]/i'</li>
333 Вы можете изменить набор декораторов, используемый элементом, если
334 хотите иметь другой результат вывода; более подробную информацию
335 читайте в разделе о декораторах.
339 Форма сама по себе просто производит обход содержащегося в ней
340 списка элементов и окружает получившийся вывод тегами
341 <code><form></code>. Переданные вами <code>action</code> и
342 <code>method</code> устанавливаются в качестве атрибутов тега
343 <code><form></code> - так же, как и остальные атрибуты,
344 установленные через семейство методов
345 <code>setAttribs()</code>.
349 Элементы обходятся в том же порядке, в котором они были
350 зарегистрированы, но если ваш элемент содержит атрибут order, то он
351 используется для сортировки. Вы можете установить порядок элемента,
355 <programlisting language="php"><![CDATA[
356 $element->setOrder(10);
361 Или путем передачи в качестве опции при создании элемента:
364 <programlisting language="php"><![CDATA[
365 $form->addElement('text', 'username', array('order' => 10));
370 <sect2 id="zend.form.quickstart.validate">
371 <title>Проверка корректности данных формы</title>
374 После того, как получены данные формы, нужно их проверить
375 и выяснить, правильно ли заполнена форма. Для всех элементов
376 производится проверка переданных
377 данных на наличие ключа, соответствующего имени элемента. Если этот
378 ключ не найден, и элемент при этом помечен как обязательный, то для
379 проверки на корректность используется значение null.
383 Откуда идут данные? Вы можете использовать <varname>$_POST</varname>,
384 <varname>$_GET</varname>, и любые другие источники данных
385 (например, запросы веб-сервисов):
388 <programlisting language="php"><![CDATA[
389 if ($form->isValid($_POST)) {
398 Вам может прийти в голову идея проверять данные одного элемента или
399 группы элементов с помощью AJAX-запросов.
400 Метод <code>isValidPartial()</code> будет проверять на корректность
401 данные части формы. Его отличие от <code>isValid()</code> состоит в
402 том, что если в данных формы отсутствует какой-либо ключ, то для
403 этого элемента не будут производиться проверки на корректность
407 <programlisting language="php"><![CDATA[
408 if ($form->isValidPartial($_POST)) {
409 // все предоставленные элементы прошли все проверки на корректность
411 // один или более элементов не прошли проверку на корректность
417 Для проверки части формы может также использоваться метод
418 <code>processAjax()</code>. В отличие от
419 <code>isValidPartial()</code>, в случае неуспеха он возвращает
420 строку в формате JSON, содержащую сообщения об ошибках заполнения.
424 Если проверка на корректность заполнения была пройдена успешно,
425 то вы можете извлечь прошедшие фильтрацию данные:
428 <programlisting language="php"><![CDATA[
429 $values = $form->getValues();
434 Для того, чтобы извлечь нефильтрованные данные, используйте:
437 <programlisting language="php"><![CDATA[
438 $unfiltered = $form->getUnfilteredValues();
443 <sect2 id="zend.form.quickstart.errorstatus">
444 <title>Получение статуса ошибки</title>
447 А что в том случае, если форма не прошла проверку на корректность?
448 Как правило, вы можете просто вывести ее снова, и сообщения
449 об ошибках будут отображены, если вы используете
450 декораторы по умолчанию:
453 <programlisting language="php"><![CDATA[
454 if (!$form->isValid($_POST)) {
457 // или присвойте ее объекту вида и произведите его рендеринг...
458 $this->view->form = $form;
459 return $this->render('form');
465 Если нужно проанализировать ошибки, то есть два способа их
466 получения. <code>getErrors()</code> возвращает ассоциативный массив
467 имен элементов и кодов ошибок (где коды ошибок представлены в виде
468 массива). <code>getMessages()</code> возвращает ассоциативный массив
469 имен элементов и сообщений об ошибках (где сообщения об ошибках
470 представлены в виде ассоциативного массива пар 'код
471 ошибки'/'сообщение об ошибке'). Если элемент не имеет ошибок, то он
472 не будет включен в массив.
476 <sect2 id="zend.form.quickstart.puttingtogether">
477 <title>Объединяя изложенное</title>
480 Давайте создадим простую форму для входа на сайт. Для нее будут
481 нужны следующие элементы:
485 <listitem><para>username</para></listitem>
486 <listitem><para>password</para></listitem>
487 <listitem><para>submit</para></listitem>
491 Для примера предположим, что корректное имя пользователя должно
492 содержать только буквенно-цифровые символы, начинаться с буквы,
493 иметь длину не меньше 6 и не больше 20 символов, кроме этого, имена
494 пользователей должны быть приведены к нижнему регистру. Пароль
495 должен содержать как минимум 6 символов. Переданное значение кнопки
496 использоваться не будет, поэтому проверка для нее может не
501 Мы используем мощь конфигурационных опций <code>Zend_Form</code> для
505 <programlisting language="php"><![CDATA[
506 $form = new Zend_Form();
507 $form->setAction('/user/login')
510 // Создание и конфигурирование элемента username
511 $username = $form->createElement('text', 'username');
512 $username->addValidator('alnum')
513 ->addValidator('regex', false, array('/^[a-z]+/'))
514 ->addValidator('stringLength', false, array(6, 20))
516 ->addFilter('StringToLower');
518 // Создание и конфигурирование элемента password
519 $password = $form->createElement('password', 'password');
520 $password->addValidator('StringLength', false, array(6))
523 // Добавление элементов в форму:
524 $form->addElement($username)
525 ->addElement($password)
526 // addElement() используется в качестве "фабрики"
527 // для создания кнопки 'Login':
528 ->addElement('submit', 'login', array('label' => 'Login'));
533 Затем создается контроллер для отображения формы и ее обработки:
536 <programlisting language="php"><![CDATA[
537 class UserController extends Zend_Controller_Action
539 public function getForm()
541 // здесь должен быть код для создания формы, приведенный выше
545 public function indexAction()
547 // рендеринг user/form.phtml
548 $this->view->form = $this->getForm();
549 $this->render('form');
552 public function loginAction()
554 if (!$this->getRequest()->isPost()) {
555 return $this->_forward('index');
557 $form = $this->getForm();
558 if (!$form->isValid($_POST)) {
559 // проверка на корректность не пройдена, выводим форму снова
561 return $this->render('form');
564 $values = $form->getValues();
572 ...и скрипт вида для отображения формы:
575 <programlisting language="php"><![CDATA[
576 <h2>Please login:</h2>
582 Как вы наверное заметили, код контроллера не является полным -
583 после успешно проведенной проверки должна производиться авторизация
584 пользователя (например, используя <code>Zend_Auth</code>).
588 <sect2 id="zend.form.quickstart.config">
589 <title>Использование объекта Zend_Config</title>
592 Все классы <code>Zend_Form</code> можно конфигурировать, используя
593 <code>Zend_Config</code>. Вы можете передавать объект
594 <code>Zend_Config</code> либо конструктору, либо через метод
595 <code>setConfig()</code>. Посмотрим, как можно создать описанную
596 выше форму, используя файл INI. Во-первых, будем следовать
597 рекомендации размещать конфигурации в разделах, отражающих
598 местонахождение релиза, и сфокусируемся на разделе 'development'.
599 Во-вторых, установим раздел для данного контроллера ('user') и
600 ключ для формы ('login'):
603 <programlisting language="ini"><![CDATA[
605 ; общие метаданные для формы
606 user.login.action = "/user/login"
607 user.login.method = "post"
610 user.login.elements.username.type = "text"
611 user.login.elements.username.options.validators.alnum.validator = "alnum"
612 user.login.elements.username.options.validators.regex.validator = "regex"
613 user.login.elements.username.options.validators.regex.options.pattern = "/^[a-z]/i"
614 user.login.elements.username.options.validators.strlen.validator = "StringLength"
615 user.login.elements.username.options.validators.strlen.options.min = "6"
616 user.login.elements.username.options.validators.strlen.options.max = "20"
617 user.login.elements.username.options.required = true
618 user.login.elements.username.options.filters.lower.filter = "StringToLower"
621 user.login.elements.password.type = "password"
622 user.login.elements.password.options.validators.strlen.validator = "StringLength"
623 user.login.elements.password.options.validators.strlen.options.min = "6"
624 user.login.elements.password.options.required = true
627 user.login.elements.submit.type = "submit"
631 Вы можете потом передать это конструктору формы:
634 <programlisting language="php"><![CDATA[
635 $config = new Zend_Config_Ini($configFile, 'development');
636 $form = new Zend_Form($config->user->login);
640 ... и вся форма будет определена.
644 <sect2 id="zend.form.quickstart.conclusion">
645 <title>Заключение</title>
648 Надеемся, что благодаря этому небольшому обучающему руководству вы
649 смогли получить представление о мощи и гибкости
650 <code>Zend_Form</code>. Для получения более подробной
651 информации читайте раздел далее.