Работа с формами
В данном разделе мы обсудим получение данных от пользователя. На странице будет располагаться форма с полями для ввода имени и 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
заполнен пользовательскими данными, то для их проверки вы можете вызвать метод
[[yii\base\Model::validate()|validate()]]. В случае неудачной проверки свойство [[yii\base\Model::hasErrors|hasErrors]]
станет равным true
. С помощью [[yii\base\Model::getErrors|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 формы, то для проверки данных будет вызван метод [[yii\base\Model::validate()|validate()]].
Если всё в порядке, действие отобразит представление entry-confirm
, которое показывает пользователю введенные им данные.
В противном случае будет отображено представление entry
, которое содержит HTML форму и ошибки проверки данных, если
они есть.
Info:
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>Вы ввели следующую информацию:</p>
<ul>
<li><label>Name</label>: <?= 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 формы представление использует мощный виджет [[yii\widgets\ActiveForm|ActiveForm]].
Методы begin()
и end()
выводят открывающий и закрывающий теги формы. Между этими вызовами создаются поля ввода при
помощи метода [[yii\widgets\ActiveForm::field()|field()]]. Первым идёт поле для "name", вторым — для "email".
Далее для генерации кнопки отправки данных вызывается метод [[yii\helpers\Html::submitButton()]].
Попробуем
Чтобы увидеть всё созданное в работе, откройте в браузере следующий URL:
http://hostname/index.php?r=site/entry
Вы увидите страницу с формой и двумя полями для ввода. Перед каждым полем имеется подпись, которая указывает, какую информацию следует вводить. Если вы нажмёте на кнопку отправки без ввода данных или если вы введете email в неверном формате, вы увидите сообщение с ошибкой рядом с каждым проблемным полем.
После ввода верных данных и их отправки, вы увидите страницу с данными, которые вы только что ввели.
Как работает вся эта «магия»
Вы, скорее всего, задаётесь вопросом о том, как же эта HTML форма работает на самом деле. Весь процесс может показаться немного волшебным: то как показываются подписи к полям, ошибки проверки данных при некорректном вводе и то что всё это происходит без перезагрузки страницы.
Да, проверка данных на самом деле происходит и на стороне клиента при помощи JavaScript и на стороне сервера.
[[yii\widgets\ActiveForm]] достаточно продуман, чтобы взять правила проверки, которые вы объявили в EntryForm
,
преобразовать их в JavaScript код и использовать его для проведения проверок. На случай отключения JavaScript в браузере
валидация проводится и на стороне сервера как показано в методе actionEntry()
. Это даёт уверенность в том, что данные
корректны при любых обстоятельствах.
Подписи для полей генерируются методом field()
, на основе имён свойств модели. Например, подпись Name
генерируется
для свойства name
. Вы можете модифицировать подписи следующим образом:
<?= $form->field($model, 'name')->label('Ваше имя') ?>
<?= $form->field($model, 'email')->label('Ваш Email') ?>
Info: В Yii есть множество виджетов, позволяющих быстро строить сложные и динамичные представления. Как вы узнаете позже, разрабатывать новые виджеты очень просто. Многое из представлений можно вынести в виджеты, чтобы использовать это повторно в других местах и упростить тем самым разработку в будущем.
Заключение
В данном разделе вы попробовали каждую часть шаблона проектирования MVC. Вы изучили как создавать классы моделей для обработки и проверки пользовательских данных.
Также, вы изучили как получать данные от пользователя и как показать данные пользователю. Это задача может занимать в процессе разработки значительное время. Yii предоставляет мощные виджеты, которые делают задачу максимально простой.
В следующем разделе вы изучите как работать с базами данных, что требуется в большинстве приложений.