2008 Апрель 18 | Кирилл Павлюков
Апр 18

Анализируя статистику поисковых запросов, по которым вы находите мой блог, я заметил, что много людей ищут примеры работы с Zend_Form. Для меня это показалось несколько странным, так как компонент Zend_Form хорошо документирован в руководстве. Но чего не сделаешь по просьбам читателей :-)

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

Для начала разберемся, что позволяет делать Zend_Form:

  • генерировать формы;
  • валидировать их (проверять введенные пользователем данные);
  • выводить ошибки.

Логично, что одна и та же форма может быть востребована несколько раз. Из этого следует, что код генерации формы можно вынести в отдельный метод для многократного использования. Так мы и поступим, создав действия getRegistrationForm и getLoginForm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
private function getLoginForm()
{
    $translate = include(APP_DIR . DIRECTORY_SEPARATOR . 'translation.php');
    $translator = new Zend_Translate_Adapter_Array($translate);

    $form = new Zend_Form();
    $form->setAction('/auth/login')
         ->setMethod('post')
         ->setTranslator($translator);
    $form->addElements(array(
        new Zend_Form_Element_Text('email', array(
            'required' => true,
            'label' => 'Адрес e-mail:',
            'description' => 'Е-меил используется в качестве логина для входа на сайт',
            'validators' => array(
                array('NotEmpty', true),
                'EmailAddress'
                ),
            'decorators' => array(
                array('ViewHelper'),
                array('Errors'),
                array('HtmlTag', array('tag' => 'dd')),
                array('Label', array('tag' => 'dt','requiredSuffix' => ' (*)')),
                array('Description'),
                )
            )),
        new Zend_Form_Element_Password('password',array(
            'required' => true,
            'label' => 'Пароль:',
            'description' => 'Выберите себе пароль',
            'validators' => array(
                array('NotEmpty', true),
                array('StringLength', true, array('min' => 6)),
                'Alnum'
                ),
            'decorators' => array(
                array('ViewHelper'),
                array('Errors'),
                array('HtmlTag', array('tag' => 'dd')),
                array('Label', array('tag' => 'dt','requiredSuffix' => ' (*)')),
                )
            )),
        new Zend_Form_Element_Submit('Войти',array(
            'decorators' => array(
                array('ViewHelper'),
                array('HtmlTag', array('tag' => 'center')),
                )
            ))
        ));
       
    return $form;
}
   
private function getRegistrationForm()
{
    $translate = include(APP_DIR . DIRECTORY_SEPARATOR . 'translation.php');
    $translator = new Zend_Translate_Adapter_Array($translate);
    $form = new Zend_Form();
    $form->setAction('/auth/registration')
         ->setMethod('post')
         ->setTranslator($translator);
    $form->addElements(array(
        new Zend_Form_Element_Text('email', array(
        'required' => true,
            'label' => 'Адрес e-mail:',
            'description' => 'Е-меил используется в качестве логина для входа на сайт',
            'validators' => array(
                array('NotEmpty', true),
                array(new My_Validate_Unique('users','email'), true),
                'EmailAddress'
                ),
            'decorators' => array(
                array('ViewHelper'),
                array('Errors'),
                array('HtmlTag', array('tag' => 'dd')),
                array('Label', array('tag' => 'dt','requiredSuffix' => ' (*)')),
                array('Description'),
                )
            )),
        new Zend_Form_Element_Password('password',array(
            'required' => true,
            'label' => 'Пароль:',
            'description' => 'Выберите себе пароль',
            'validators' => array(
                array('NotEmpty', true),
                array('StringLength', true, array('min' => 6)),
                'Alnum'
                ),
            'decorators' => array(
                array('ViewHelper'),
                array('Errors'),
                array('HtmlTag', array('tag' => 'dd')),
                array('Label', array('tag' => 'dt','requiredSuffix' => ' (*)')),
                )
            )),
        new Zend_Form_Element_Password('password_confirm',array(
            'required' => true,
            'label' => 'Повтор пароля',
            'description' => 'Повторите ввод пароля',
            'validators' => array(
                array(new My_Validate_Password(), true)
                ),
            'decorators' => array(
                array('ViewHelper'),
                array('Errors'),
                array('HtmlTag', array('tag' => 'dd')),
                array('Label', array('tag' => 'dt','requiredSuffix' => ' (*)')),
                )
            )),
        new Zend_Form_Element_Text('name', array(
            'required' => false,
            'label' => 'Ваше имя',
            'validators' => array(
                'Alnum'
                ),
            'decorators' => array(
                array('ViewHelper'),
                array('Errors'),
                array('HtmlTag', array('tag' => 'dd')),
                array('Label', array('tag' => 'dt','requiredSuffix' => ' (*)')),
                )
            )),
        new Zend_Form_Element_Submit('Зарегистрировать',array(
            'decorators' => array(
                array('ViewHelper'),
                array('HtmlTag', array('tag' => 'center')),
                )
            ))
        ));
    return $form;
}

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

Итак, формы созданы, теперь нужно их использовать :-)
Посмотрите, как выглядит действие registration:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public function registrationAction()
{
    // проверим, переданы скрипту данные по методу POST
    if (!$this->getRequest()->isPost()) {
        // если данные не переданы, просто передадим в скрипт вида форму
        return $this->view->form = $this->getRegistrationForm();
    } else {
        $form = $this->getRegistrationForm();
        // если данные переданы, проверим их на корректность
        if (!$form->isValid($_POST)) {
            // если данные не корректны, возвращаем форму в скрипт вида
            // Zend_Form сам отобразит сообщения об ошибках
            return $this->view->form = $form;
        } else {
            // если данные верны, сохраним их в БД
            /** @var Zend_Db_Adapter_Abstract */        
            $db = Zend_Registry::get('db');
       
            if ($db->insert('users', array(
                'name' => $_POST['name'],
                'email' => $_POST['email'],
                'passwd' => new Zend_Db_Expr("MD5('{$_POST['password']}')"),
                ))) {
                $this->view->success = true;
            }
        }
    }
}

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

1
<?php echo $this->form; ?>

Во-вторых, можно вывести поэлементно. Для этого в нужном месте вызывается код

1
<?php echo $this->form->element; ?>

, в котором element - это имя соответствующего элемента формы.

Автор: Кирилл Павлюков \\ Метки: , , ,