# Работа с формами ¶

В данном разделе мы обсудим получение данных от пользователя. На странице будет располагаться форма с полями для ввода имени и email. Полученные данные будут показаны на странице для их подтверждения.

Чтобы достичь этой цели, помимо создания действия и двух представлений вы создадите модель.

В данном руководстве вы изучите:

- Как создать модель для данных, введённых пользователем;
- Как объявить правила проверки введённых данных;
- Как создать HTML-форму в представлении.

## Создание модели ¶

В файле `models/EntryForm.php` создайте класс модели `EntryForm` как показано ниже. Он будет использоваться для хранения данных, введённых пользователем. Подробно об именовании файлов классов читайте в разделе «Автозагрузка классов».

    <?php

    namespace app\models;

    use yii\base\Model;

    class EntryForm extends Model
    {
        public $name;
        public $email;

        public function rules()
        {
            return [
                [['name', 'email'], 'required'],
                ['email', 'email'],
            ];
        }
    }

Данный класс расширяет класс yii\base\Model, который является частью фреймворка и обычно используется для работы с данными форм.

Класс содержит 2 публичных свойства `name` и `email`, которые используются для хранения данных, введённых пользователем. Он также содержит метод `rules()`, который возвращает набор правил проверки данных. Правила, объявленные в коде выше означают следующее:

- Поля `name` и `email` обязательны для заполнения;
- В поле `email` должен быть правильный адрес email.

Если объект `EntryForm` заполнен пользовательскими данными, то для их проверки вы можете вызвать метод validate(). В случае неудачной проверки свойство hasErrors станет равным `true`. С помощью errors можно узнать, какие именно ошибки возникли.

## Создание действия ¶

Далее создайте действие `entry` в контроллере `site`, точно так же, как вы делали это ранее.

    <?php

    namespace app\controllers;

    use Yii;
    use yii\web\Controller;
    use app\models\EntryForm;

    class SiteController extends Controller
    {
        // ...существующий код...

        public function actionEntry()
        {
            $model = new EntryForm();

            if ($model->load(Yii::$app->request->post()) && $model->validate()) {
                // данные в $model удачно проверены

                // делаем что-то полезное с $model ...

                return $this->render('entry-confirm', ['model' => $model]);
            } else {
                // либо страница отображается первый раз, либо есть ошибка в данных
                return $this->render('entry', ['model' => $model]);
            }
        }
    }

Действие создает объект `EntryForm`. Затем оно пытается заполнить модель данными из массива `$_POST`, доступ к которому обеспечивает Yii при помощи yii\web\Request::post(). Если модель успешно заполнена, то есть пользователь отправил данные из HTML-формы, то для проверки данных будет вызван метод validate().

Если всё в порядке, действие отобразит представление `entry-confirm`, которое показывает пользователю введенные им данные. В противном случае будет отображено представление `entry`, которое содержит HTML-форму и ошибки проверки данных, если они есть.

> Информация: `Yii::$app` представляет собой глобально доступный экземпляр-одиночку приложения (singleton). Одновременно это Service Locator, дающий доступ к компонентам вроде `request`, `response`, `db` и так далее. В коде выше для доступа к данным из `$_POST` был использован компонент `request`.

## Создание представления ¶

В заключение создаём два представления с именами `entry-confirm` и `entry`, которые отображаются действием `entry` из предыдущего подраздела.

Представление `entry-confirm` просто отображает имя и email. Оно должно быть сохранено в файле `views/site/entry-confirm.php`.

    <?php
    use yii\helpers\Html;
    ?>
    <p>Выы<?= Html::encode($model->name) ?></li>
        <li><label>Email</label>: <?= Html::encode($model->email) ?></li>
    </ul>

Представление `entry` отображает HTML-форму. Оно должно быть сохранено в файле `views/site/entry.php`.

    <?php
    use yii\helpers\Html;
    use yii\widgets\ActiveForm;
    ?>
    <?php $form = ActiveForm::begin(); ?>

        <?= $form->field($model, 'name') ?>

        <?= $form->field($model, 'email') ?>

        <div class="form-group">
            <?= Html::submitButton('Отправитьclass' => 'btn btn-primary']) ?>
        </div>

    <?php ActiveForm::end(); ?>

Для построения HTML-формы представление использует мощный виджет ActiveForm. Методы `begin()` и `end()` выводят открывающий и закрывающий теги формы. Между этими вызовами создаются поля ввода при помощи метода field(). Первым идёт поле для "name", вторым — для "email". Далее для генерации кнопки отправки данных вызывается метод yii\helpers\Html::submitButton().

## Попробуем ¶

Чтобы увидеть всё созданное в работе, откройте в браузере следующий URL:

    http://hostname/index.php?r=site%2Fentry

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

После ввода верных данных и их отправки, вы увидите страницу с данными, которые вы только что ввели.

### Как работает вся эта «магия» ¶

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

Да, проверка данных на самом деле происходит и на стороне клиента при помощи JavaScript, и на стороне сервера. yii\widgets\ActiveForm достаточно продуман, чтобы взять правила проверки, которые вы объявили в `EntryForm`, преобразовать их в JavaScript код и использовать его для проведения проверок. На случай отключения JavaScript в браузере валидация проводится и на стороне сервера как показано в методе `actionEntry()`. Это даёт уверенность в том, что данные корректны при любых обстоятельствах.

Подписи для полей генерируются методом `field()`, на основе имён свойств модели. Например, подпись `Name` генерируется для свойства `name`. Вы можете модифицировать подписи следующим образом:

    <?= $form->field($model, 'name')->label('Ваше имя') ?>
    <?= $form->field($model, 'email')->label('Ваш Email') ?>

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

## Заключение ¶

В данном разделе вы попробовали каждую часть шаблона проектирования MVC. Вы изучили как создавать классы моделей для обработки и проверки пользовательских данных.

Также, вы изучили как получать данные от пользователя и как показать данные пользователю. Это задача может занимать в процессе разработки значительное время. Yii предоставляет мощные виджеты, которые делают задачу максимально простой.

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