Работа с формами в Zend Framework
На первый взгляд, работа с формами в Zend Framework может показаться намного сложнее, нежели стандартная обработка форм в PHP. Но это до того момента, когда вам понадобится валидировать данные формы и выдавать соответствующие ошибки. Думаю, что попробовав, вы поймете…
Форму описывает объект класса Zend_Form. Работа начинается с создания объекта этого класса. Давайте создатим этот объект:
$form = new Zend_Form();
$form->setMethod('post');
Видно, что форма передает данные методом post. У объекта класса Zend_Form есть множество методов, устанавливающих те или иные параметры формы.
Далее к форме добавим текстовое поле, которое принимает только символы соответствующие алфавиту, а также переводит введенные символы в нижний регистр. Это поле обязательно для ввода.
$text = new Zend_Form_Element_Text('text_id');
$text->addValidator('alpha');
$text->addFilter('StringToLower');
$text->setRequired(true);
$form->addElement($text);
$submit = new Zend_Form_Element_Submit('submit');
$form->addElement($submit);
Теперь эту форму можно вывести на страницу:
<html><body> <?= $this->form ?> </body></html>
Форма готова. Осталось написать метод для ее обработки. Для простоты будет дополнен метод, создающий форму. (Удобно вынести код, создающий форму в отдельный метод) Если форма не прошла валидацию, то выводим ее еще раз. При этом будут указаны ошибки допущенные пользователем. Тексты ошибок появятся рядом с невалидными полями.
if ($this->getRequest()->isPost()) {
if (!$form->isValid($_POST)) {
$this->render('form');
} else {
//Save data and redirect
}
}
При создании объекта формы и элемента формы, по умолчанию устанавливаются некоторые декораторы. Так, например, если установить свойство label объекта элемента формы, на странице, перед этим элементом появится текст, соответствующий значунию label. Также можно написать свои декораторы. Этим мы и займемся…
Давайте напишем декоратор, который помещает элемент в строку таблицы, в первом столбце которой будет выведен текст свойства label этого элемента. Для этого необходимо создать классы декораторов:
class Vaniashev_Decorator_TestElement extends Zend_Form_Decorator_Abstract{
public function render($content){
return $content.'<tr><td>'.$this->getElement()->getLabel().'</td>.
'<td>'.$this->buildInput().'</td></tr>';
}
public function buildInput()
{
$element = $this->getElement();
$helper = $element->helper;
return $element->getView()->$helper(
$element->getName(),
$element->getValue(),
$element->getAttribs(),
$element->options
);
}
}
class Vaniashev_Decorator_Button extends Zend_Form_Decorator_Abstract {
public function render($content){
return $content.'<tr><td> </td>' .
'<td>'.$this->buildInput().'</td></trv';
}
public function buildInput()
{
$element = $this->getElement();
$helper = $element->helper;
return $element->getView()->$helper(
$element->getName(),
$element->getLabel(),
$element->getAttribs(),
$element->options
);
}
}
Файлы декораторов поместим в папку vaniashev/decorators/ и назовем соответственно TestElement.php и Button.php. Чтобы использовать эти декораторы, необходимо указать форме, где их искать. Для этого, в контроллере где создается форма выполним: $form->addPrefixPath(’Vaniashev_Decorator’, ‘vaniashev/decorator’, Zend_Form::DECORATOR). Благодая этому, форма и все ее элементы будут искать декораторы в указанной папке. Но для этого, каждому элементу необходимо указать имя используемого декоратора. Например $text->setDecorators(array(’TestElement’)). Причем этот метод можно вызывать только после того, как элемент добавлен в форму, т.к. до этого элемент не владеет информацией о путях к декораторам.
Так как мы изменили разметку формы, ошибки валидации больше не выводятся. Чтобы снова их увидеть, добавим в декоратор элемента следующие строки:
public function buildErrors()
{
$element = $this->getElement();
$messages = $element->getMessages();
if (empty($messages)) {
return '';
}
$out = '';
foreach ($messages as $m){
$out.= $m.'. ';
}
return '<span style="color:red"> '.$out.'</span>';
}
Также вызов этого метода необходимо добавить в метод render(). Теперь наша форма снова оповещает нас об ошибках. Но как изменить текст выводимых ошибок? Текстовые сообщения об ошибках можно изменить, передав их как третий параметр метода addValidator. Например для нашего элемента:
$text->addValidator('alpha', false, array('messages'=>array('notAlpha'=>'Text of error')));
Конечно, в этой статье освещены не все варианты работы с формами. Если у вас имеются какие-либо вопросы по данной теме, задавайте их в комментариях. Отвечу на все вопросы.
Также, возможно, вам будут интересны методы аутентификации в Zend Framework.

02 Сен 2008 в 3:31 пп
А если есть например несколько кнопок submit и по каждой из них надо выполнить разные действия, то как в таком случае различить, какая из кнопок была нажата?
Спасибо.
02 Сен 2008 в 9:15 пп
Спасибо, хороший вопрос!
Допустим, мы добавили в форму 2 кнопки:
$submit = new Zend_Form_Element_Submit(’save’);
$preview = new Zend_Form_Element_Submit(’preview’);
Теперь вместо строки “//Save data and redirect” мы можем написать следующее:
if ($form->getElement(’save’)->isChecked()){
//save data
}
if ($form->getElement(’preview’)->isChecked()){
//preview data
}
26 Сен 2008 в 3:27 дп
Посоветовали на каком-то из форумов ваш блог. Благодарен вам и тем, кто подсказал. Записываюсь постоянным посетителем и подпишусь на РСС
26 Сен 2008 в 10:02 дп
Спасибо! Надеюсь блог будет Вам полезен!
26 Сен 2008 в 12:43 пп
Похоже метод buildErrors нужно вручную вызывать.
26 Сен 2008 в 1:57 пп
Его вызов должен быть в методе render. Например так:
public function render($content){
return $content.’<tr><td> </td><td>’.$this->buildInput().’</td><td>’.buildErrors().’</td></tr>’;
}
21 Окт 2008 в 11:56 дп
Как добавить несколько кнопок в ряд.
Например Submit, Submit+, Cancel . Нужно использовать декораторы, но каким образом можно указатЬ, чтобы кнопки шли вряд под формой, а не друг под другом
21 Окт 2008 в 5:37 пп
Например, функцию render() в Vaniashev_Decorator_Button, можно изменить на:
public function render($content){
return $content.’<span>’.$this->buildInput().’</span>’;
}
И применить этот декоратор ко всем этим кнопкам.
24 Окт 2008 в 4:00 пп
Спасибо за интересный материал. У меня возникли сложности при работе с Zend_form. Вот например банальнейшая задача - форма регистрации на сайте - как сделать два поля для ввода пароля и для его подтверждения и выдавать сообщение в случае ошибки? Как сделать, чтобы пользователи не могли ввести логин, уже зарегистрированный на сайте? Эти вроде бы простые задачи поставили меня в тупик при условии использования Zend_form.
30 Окт 2008 в 8:17 пп
[...] комментариях к статье “Работа с формами в Zend Framework“, Сергей задал вопрос о реализации проверки [...]
30 Окт 2008 в 8:19 пп
Сергей, ваш вопрос побудил меня написать отдельную статью о валидаторах. Все желающие могут посмотреть ее по адресу http://pro-dev.ru/?p=63 . По прежнему жду ваших вопросов и замечаний.
09 Ноя 2008 в 11:56 дп
я вот как начинающий что скажу-ну напишите вы мелкий единый пример раз блог ведете-сделал-а в зенде этом никак не пойму откуда 404 ошибка проходит и пост просто не идет. ну думаю гдето ошибся-беру пример от самого зенда-разворачиваю все по инструкции-ихний guestbook форму смотрю-все вроде правильно и с этим блогом соответствует-запускаю-никакого толку-все также 404 ошибка если смотреть логи и смотреть в плагиге файрфокса а внешне-снова открывается все та же форма с все теми же пустыми полями-неужто просто 1-2 файла с комментариями на рабочем примере а не вот такое философствование хуже?
10 Ноя 2008 в 4:46 пп
Вообще может быть много различных проблем. А простейший контроллер у вас работает? Проверьте пути в index.php
11 Ноя 2008 в 12:26 пп
Вот именно ПРОСТЕЙШИЙ примерчик и увидеть бы захотелось. нашел книгу одного америкоса - так тот дедолага в книге одно, а коде другое строчит. Примеры впрочем его запустил (странно только отчего программист не использовал относительные пути в индексе и бутстрапе а везде прописывал абсолютные-пришлось править/учесть еще что у него все для виндовс версии а у мня линукс/) Решил раскопать-почему же гостевая зенда не пашет-не нашел. Вот все прально в ихней теории-а фоновый 404 все равно идет и регистрацию сделать нереально. Ну раз так -взял pradoframework поставил-посмотрел доку-все заработало. Глубже вник-чтото вроде (по классам) напоминает-присмотрелся-мама родная- NET подход на PHP
Вот теперь и на перепутье-или в zend убиться или в prado податься
28 Ноя 2008 в 12:58 пп
[...] вы хотите, чтобы в вашей форме, созданной с помощью ZendForm, было обязательное поле, то логичнее всего, было бы [...]