Zend_Form - Быстрый старт Данное руководство охватывает основы создания форм, проверки корректности данных и визуализиции с использованием Zend_Form. Создание объекта формы Объекты форм создаются через простое инстанцирование Zend_Form: Для более сложных случаев использования вы можете создавать подклассы Zend_Form, но простые формы вы можете создавать, используя объект Zend_Form. Если вы хотите указать атрибуты action и method (что во всех случаях является хорошей идеей), то можете сделать это с использованием аксессоров setAction() и setMethod(): setAction('/resource/process') ->setMethod('post'); ]]> Приведенный выше код устанавливает значение атрибута action равным "/resource/process" и указывает способ отправки данных - HTTP POST. Эти атрибуты будут выведены после окончательного рендеринга формы. Вы можете установить дополнительные HTML-атрибуты для тега <form>, используя методы setAttrib() и setAttribs(). Например, если нужно установить идентификатор элемента формы, то установите атрибут "id": setAttrib('id', 'login'); ]]> Добавление элементов в форму Форма без элементов бесмысленна. Zend_Form поставляется с некоторым начальным набором элементов, которые отвечают за рендеринг XHTML-кода с использованием помощников Zend_View. В этот список входят элементы: button (кнопка) checkbox (флажок опций, или несколько флажков опций через multiCheckbox) hidden (спрятанное поле) image (изображение) password (пароль) radio (переключатель) reset (кнопка сброса) select (выпадающий список - как обычный, так multi-select) submit (кнопка отправки) text (текстовое поле) textarea (текстовая область) Есть два способа добавления элементов в форму - вы можете инстанцировать нужные элементы и передавать их объекту формы, или передавать только тип элемента, в этом случае Zend_Form инстанцирует соответствующий объект за вас. Некоторые примеры: addElement(new Zend_Form_Element_Text('username')); // Передача типа элемента объекту формы $form->addElement('text', 'username'); ]]> По умолчанию элементы не имеют никаких валидаторов или фильтров. Это означает, что вам нужно установить к своим элементам, как минимум, валидаторы, и, возможно, фильтры. Вы можете делать это (a) до передачи элементов в форму, (b) через опции конфигурирования, которые передаются при создании элемента через Zend_Form, или (с) путем извлечения элементов формы из объекта формы и их конфигурирования. Сначала рассмотрим создание валидаторов для конкретного объекта элемента. Вы можете передавать объекты Zend_Validate_* или имена валидаторов: addValidator(new Zend_Validate_Alnum()); // Передача имени валидатора: $username->addValidator('alnum'); ]]> В случае использования второго варианта, если валидатор принимает аргументы конструктора, то вы можете передавать их через массив как третий параметр: addValidator('regex', false, array('/^[a-z]/i')); ]]> (Второй параметр используется для указания того, должен ли валидатор в том случае, если данные не прошли проверку, прерывать дальнейшую проверку в цепочке валидаторов; по умолчанию он равен false.) Вы можете также указать элемент как обязательный для заполнения. Это может быть сделано как с помощью аксессора, так и путем передачи определенной опции при создании элемента. В первом случае: setRequired(true); ]]> Если элемент обязателен для заполнения, то в начало цепочки валидаторов добавляется валидатор 'NotEmpty', который проверяет, имеет ли элемент значение. Фильтры регистрируются в основном так же, как и валидаторы. Для демонстрации добавим фильтр для приведения значения к нижнему регистру: addFilter('StringToLower'); ]]> Таким образом, окончательно установка элемента получится такой, как показано ниже: addValidator('alnum') ->addValidator('regex', false, array('/^[a-z]/')) ->setRequired(true) ->addFilter('StringToLower'); // или в более компактной форме: $username->addValidators(array('alnum', array('regex', false, '/^[a-z]/i') )) ->setRequired(true) ->addFilters(array('StringToLower')); ]]> Выполнение этих действий для каждого элемента по отдельности может показаться несколько утомительным. Попробуем вариант (b) из перечисленных выше. Когда мы создаем новый элемент, используя Zend_Form::addElement() в качестве фабрики, то можем опционально передавать опции конфигурирования. Они могут включать в себя валидаторы и фильтры для использования. Таким образом, чтобы неявным образом сделать все это, попробуйте следующее: addElement('text', 'username', array( 'validators' => array( 'alnum', array('regex', false, '/^[a-z]/i') ), 'required' => true, 'filters' => array('StringToLower'), )); ]]> Если вы обнаружили, что настраиваете элементы, используя одни и те же опции во многих местах, то можете создать подкласс Zend_Form_Element и использовать его вместо выполнения этих процедур; это может избавить от лишней работы по набору кода. Визуализация формы Визуализация формы производится легко. Большинство элементов использует помощника Zend_View для генерации вывода и поэтому нуждаются в объекте вида для выполнения рендеринга. Есть два способа запустить рендеринг: использовать метод формы render() или просто вывести форму с помощью echo. render($view); // Предполагается, что объект вида уже был установлен ранее через setView(): echo $form; ]]> По умолчанию Zend_Form будет пытаться использовать объект вида, инициализированный в ViewRenderer, это означает, что вам не нужно будет вручную устанавливать объект вида при использовании MVC Zend Framework-а. Код для визуализации формы в скрипте вида весьма прост: form ?> ]]> Внутри себя Zend_Form использует "декораторы" для выполнения визуализации. Эти декораторы могут замещать содержимое переданного элемента, производить добавления в его начало и конец, производить наблюдение за ним. В результате вы можете комбинировать несколько декораторов для достижения нужного эффекта. По умолчанию в Zend_Form_Element используется четыре декоратора для получения нужного вывода; их установка выглядит приблизительно так: addDecorators(array( 'ViewHelper', 'Errors', array('HtmlTag', array('tag' => 'dd')), array('Label', array('tag' => 'dt')), )); ]]> Код выше создает вывод наподобие следующего: Вы можете изменить набор декораторов, используемый элементом, если хотите иметь другой результат вывода; более подробную информацию читайте в разделе о декораторах. Форма сама по себе просто производит обход содержащегося в ней списка элементов и окружает получившийся вывод тегами <form>. Переданные вами action и method устанавливаются в качестве атрибутов тега <form> - так же, как и остальные атрибуты, установленные через семейство методов setAttribs(). Элементы обходятся в том же порядке, в котором они были зарегистрированы, но если ваш элемент содержит атрибут order, то он используется для сортировки. Вы можете установить порядок элемента, используя: setOrder(10); ]]> Или путем передачи в качестве опции при создании элемента: addElement('text', 'username', array('order' => 10)); ]]> Проверка корректности данных формы После того, как получены данные формы, нужно их проверить и выяснить, правильно ли заполнена форма. Для всех элементов производится проверка переданных данных на наличие ключа, соответствующего имени элемента. Если этот ключ не найден, и элемент при этом помечен как обязательный, то для проверки на корректность используется значение null. Откуда идут данные? Вы можете использовать $_POST, $_GET, и любые другие источники данных (например, запросы веб-сервисов): isValid($_POST)) { // успех } else { // неудача } ]]> Вам может прийти в голову идея проверять данные одного элемента или группы элементов с помощью AJAX-запросов. Метод isValidPartial() будет проверять на корректность данные части формы. Его отличие от isValid() состоит в том, что если в данных формы отсутствует какой-либо ключ, то для этого элемента не будут производиться проверки на корректность заполнения: isValidPartial($_POST)) { // все предоставленные элементы прошли все проверки на корректность } else { // один или более элементов не прошли проверку на корректность } ]]> Для проверки части формы может также использоваться метод processAjax(). В отличие от isValidPartial(), в случае неуспеха он возвращает строку в формате JSON, содержащую сообщения об ошибках заполнения. Если проверка на корректность заполнения была пройдена успешно, то вы можете извлечь прошедшие фильтрацию данные: getValues(); ]]> Для того, чтобы извлечь нефильтрованные данные, используйте: getUnfilteredValues(); ]]> Получение статуса ошибки А что в том случае, если форма не прошла проверку на корректность? Как правило, вы можете просто вывести ее снова, и сообщения об ошибках будут отображены, если вы используете декораторы по умолчанию: isValid($_POST)) { echo $form; // или присвойте ее объекту вида и произведите его рендеринг... $this->view->form = $form; return $this->render('form'); } ]]> Если нужно проанализировать ошибки, то есть два способа их получения. getErrors() возвращает ассоциативный массив имен элементов и кодов ошибок (где коды ошибок представлены в виде массива). getMessages() возвращает ассоциативный массив имен элементов и сообщений об ошибках (где сообщения об ошибках представлены в виде ассоциативного массива пар 'код ошибки'/'сообщение об ошибке'). Если элемент не имеет ошибок, то он не будет включен в массив. Объединяя изложенное Давайте создадим простую форму для входа на сайт. Для нее будут нужны следующие элементы: username password submit Для примера предположим, что корректное имя пользователя должно содержать только буквенно-цифровые символы, начинаться с буквы, иметь длину не меньше 6 и не больше 20 символов, кроме этого, имена пользователей должны быть приведены к нижнему регистру. Пароль должен содержать как минимум 6 символов. Переданное значение кнопки использоваться не будет, поэтому проверка для нее может не производиться. Мы используем мощь конфигурационных опций Zend_Form для построения формы: setAction('/user/login') ->setMethod('post'); // Создание и конфигурирование элемента username $username = $form->createElement('text', 'username'); $username->addValidator('alnum') ->addValidator('regex', false, array('/^[a-z]+/')) ->addValidator('stringLength', false, array(6, 20)) ->setRequired(true) ->addFilter('StringToLower'); // Создание и конфигурирование элемента password $password = $form->createElement('password', 'password'); $password->addValidator('StringLength', false, array(6)) ->setRequired(true); // Добавление элементов в форму: $form->addElement($username) ->addElement($password) // addElement() используется в качестве "фабрики" // для создания кнопки 'Login': ->addElement('submit', 'login', array('label' => 'Login')); ]]> Затем создается контроллер для отображения формы и ее обработки: view->form = $this->getForm(); $this->render('form'); } public function loginAction() { if (!$this->getRequest()->isPost()) { return $this->_forward('index'); } $form = $this->getForm(); if (!$form->isValid($_POST)) { // проверка на корректность не пройдена, выводим форму снова $this->form = $form; return $this->render('form'); } $values = $form->getValues(); // аутентификация... } } ]]> ...и скрипт вида для отображения формы: Please login: form ?> ]]> Как вы наверное заметили, код контроллера не является полным - после успешно проведенной проверки должна производиться авторизация пользователя (например, используя Zend_Auth). Использование объекта Zend_Config Все классы Zend_Form можно конфигурировать, используя Zend_Config. Вы можете передавать объект Zend_Config либо конструктору, либо через метод setConfig(). Посмотрим, как можно создать описанную выше форму, используя файл INI. Во-первых, будем следовать рекомендации размещать конфигурации в разделах, отражающих местонахождение релиза, и сфокусируемся на разделе 'development'. Во-вторых, установим раздел для данного контроллера ('user') и ключ для формы ('login'): Вы можете потом передать это конструктору формы: user->login); ]]> ... и вся форма будет определена. Заключение Надеемся, что благодаря этому небольшому обучающему руководству вы смогли получить представление о мощи и гибкости Zend_Form. Для получения более подробной информации читайте раздел далее.