Pull to refresh

PHP: Формы в Zend Framework

Формы в Zend Framework


v:1.0 19.02.2010


Перевод статьи Forms in Zend Framework.
Автор: Adrian Schneider
Перевод: Петрелевич Сергей



Меня часто спрашивают, какой мой любимый компонент в Zend Framework, и я всегда отвечаю: «Forms» (формы).
В парадигме модель-представление-контроллер формы всегда играют непростую роль. Конечно, форма — это всего лишь HTML, но для меня это нечто более абстрактное.
По сути, форма — это HTML, средствами которого пользователь вводит и получает данные, но кроме этого форма еще выполняет нормализацию, проверку, фильтрацию данных и вывод сообщений об ошибках, если они есть.
Это может потребовать довольно-таки значительного объема кода.


Если Вы можете автоматизировать все эти вещи, то Вам останется только конфигурация.
Каждая форма состоит из элементов, каждый элемент имеет несколько атрибутов, которые переопределяют функциональность формы.
Давайте рассмотрим некоторые из этих аспектов.


Создание формы


Форма — это экземпляр класса Zend_Form. Экземпляр можно создать многими способами.
Я предпочитаю создавать свои классы, наследуя класс Zend_Form. И уже в свои классы вношу необходимые мне изменения. Каждая форма состоит из нескольких важных полей (действие, метод) и содержит как минимум один элемент. Давайте посмотрим, как можно создать элемент.
Каждый элемент может иметь несколько типовых атрибутов: тип поля, метка, наименование и описание.
Давайте опишем такой элемент в ZF.
Обратите внимание, существует несколько различных способов создания форм. Это мой самый любимый способ.

$username = new Zend_Form_Element_Text('username', array(<br>        'label'       => 'Username',<br>        'description' => 'This is a description'));<br><br>* This source code was highlighted with Source Code Highlighter.

Как Вы видите, в примере я задаю все эти атрибуты.

Прим. переводчика:
тип поля — Zend_Form_Element_Text
метка (label) — 'Username'
наименование — 'username'
описание (description) — 'This is a description'


Кроме указанных выше есть еще несколько важных атрибутов элемента. Давайте добавим еще несколько.

$this->addElements(array(<br>    new Zend_Form_Element_Text('username', array(<br>     'label' => 'Username',<br>     'required' => true)),<br>    ));<br><br>* This source code was highlighted with Source Code Highlighter.

Фильтры и валидаторы


Выстраивание цепочек из фильтров и валидаторов — это одна из очень полезных особенностей компонента форм.
Фильтр — это такая штука, которая автоматически выполняет преобразования входных данных.
А валидатор — это механизм автоматической проверки данных во время обработки форм.
Эти механизмы существенно упрощают код контроллера и модели, т.к. логика перемещается в более организованную структуру.


Рассмотрим пример. На регистрационной форме находится элемент ввода имени пользователя. Надо реализовать проверку уникальности имени, имя должно состоять только из разрешенных символов и его длина должна входить в допустимый диапазон.


Если у Вас на форме есть элемент, в котором пользователь может ввести произвольный текст, например о себе, то Вы наверняка захотите применить фильтры, чтобы убедиться, что введены «чистые» данные.
Будет полезно добавить фильтры типа StripTags, чтобы убрать все теги HTML, StringTrim, чтобы убрать все лишние пробелы. Если есть желание, можно добавить фильтры для обработки BB-кодов.
Для этого вы можете создать свой собственный фильтр или использовать Callback-фильтр, который сможете использовать и в других формах.


Идея заключается в том, чтобы проверять данные как можно более тщательно, Вы должны быть уверены, что данные на 100% соответствуют вашему приложению. Если у Вас поле типа VARCHAR(255), то ограничьте поле ввода 255 символами, и Вам не придется пользоваться функциями обрезания строк.
Проявляйте максимум осторожности.


Фильтры помогают сохранить целостность данных, также могут использоваться в процессе очистки данных, введенных в форме. Если Вы позволяете пользователю что-то вводить, обязательно удаляйте все теги HTML. Думаю, Вы поняли идею…


Представляю более полный пример регистрационной формы:

$this->addElements(array(<br>  new Zend_Form_Element_Text('username', array(<br>    'label'    => 'Username',<br>    'required'   => true,<br>    'validators'  => array(<br>      array('StringLength',   false, array(4, 16)),<br>      array('Alnum'),<br>      array('Db_NoRecordExists', false, array('users', 'username'))<br>    )<br>  )),<br>  new Zend_Form_Element_Text('email', array(<br>    'label'    => 'Email Address',<br>    'required'   => true,<br>    'validators'  => array(<br>      array('EmailAddress'),<br>      array('Db_NoRecordExists', false, array('users', 'email'))<br>    )<br>  )),<br>  new Zend_Form_Element_Password('password', array(<br>    'label'    => 'Password',<br>    'required'   => true<br>  ))<br>));<br><br>* This source code was highlighted with Source Code Highlighter.

Худой контроллер, толстая модель


Для формы, описанной выше, Вы можете разработать очень простой контроллер.
Я считаю, что контроллер должен управлять логикой приложения, но не должен работать с данными.
Вот пример действия (action) для формы регистрации.

if ($this->_request->isPost()) <br>{<br>  if ($form->isValid($this->_request->getPost())) <br>  {<br>    $user->register($form->getValues());<br>    $this->redirector->goToUrl('/welcome');<br>  }<br>}<br>$this->view->form = $form;<br><br>* This source code was highlighted with Source Code Highlighter.

После того как пользователь заканчивает ввод данных, валидаторы выполняют проверку введенной информации.
Если проверка заканчивается успешно, массив данных передается в модель. К моменту передачи данных в модель все фильтры и валидаторы должны закончить свою работу. Сейчас мы уже знаем как форматировать данные и как повысить их безопасность.
В контроллере Вы можете перенаправить пользователя на другую страницу или выполнить другие действия в соответствии с логикой Вашего приложения.


Форма выводится пользователю через представление. В общем случае представление просто загружает форму и отображает ее пользователю.
Если введенные пользователем данные содержат ошибку, представление не только отобразит форму и выведет сообщения об ошибках, но и покажет введенные данные.


Скрипты представления и декораторы


Ниже показан весь код представления, с помощью которого можно отобразить форму. Если требуется дополнительная настройка формы, то ее можно выполнить средствами CSS или декораторами.

<?= $this->form ?><br><br>* This source code was highlighted with Source Code Highlighter.

По умолчанию, Zend_Form формирует вполне приличный код HTML. Я не испытываю какие-либо сложности с наложением дополнительных стилей CSS. Использование CSS хорошо вписывается в концепцию разделения различных функциональных частей приложения.
Однако, часто требуется изменить не только стиль отображения, но и расположение элементов. В Zend для этого используются декораторы. Декораторы несколько сложны для понимания, поэтому я оставлю их для следующего поста.


Взаимодействие с моделями


В соответствии с кодом нашего контроллера, в модель передается результат функции $form->getValues().
Результат этой функции — предварительно проверенный и отфильтрованный массив данных.
Вот пример:

// ...<br>public function register(array $user) {<br><br>}<br>// ...<br><br>* This source code was highlighted with Source Code Highlighter.

Я считаю, что это прекрасно. Мы работаем с очень простым интерфейсом, и нам не надо вручную указывать каждое значение, которое мы хотим передать. Конечно, это дело хозяйское, но я не понимаю людей, которые передают в модель по 5-10 значений.
Такие контроллеры непременно будут большими.
Разумеется, код не зависит от формы, поскольку работает с массивом данных. Это делает вызов модели очень простым.
Модель — это место, где должен начинаться сложный код.
При таком подходе мы можем использовать наш объект адаптера базы данных или несколько других библиотек.


Заключение


Комонент форма (form) — это один из самых больших, а может быть и самый большой компонент в Zend. Не бойтесь задавать вопросы на различных форумах, или задавайте вопросы в форме ниже, я направлю Вас на хороший ресурс. Как я уже говорил, для меня это самый полезный компонент в Zend. Я настоятельно рекомендую не пожалеть время на его изучение.


Возможно, Вас заинтересует материал по кэшированию форм.

Tags:
Hubs:
You can’t comment this publication because its author is not yet a full member of the community. You will be able to contact the author only after he or she has been invited by someone in the community. Until then, author’s username will be hidden by an alias.