Yii2 framework backup
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

244 lines
14 KiB

10 years ago
Робота з формами
================
В даному розділі буде описано як створити нову сторінку з формою для отримання даних від користувачів.
На сторінці буде розміщена форма з полями, де можна буде вказати ім’я та адресу електронної пошти.
Після отримання цих двох фрагментів інформації від користувача, сторінка відобразить введені значення знову для підтвердження.
10 years ago
Для досягнення даної цілі, крім створення [дії](structure-controllers.md) і
двох [представлень](structure-views.md), ви також створите [модель](structure-models.md).
10 years ago
В даному керівництві ви дізнаєтесь як:
10 years ago
* створити [модель](structure-models.md) для даних, введених користувачем через форму;
* оголосити правила перевірки введених даних;
* створити HTML-форму в [представленні](structure-views.md).
10 years ago
Створення моделі <span id="creating-model"></span>
----------------
10 years ago
Дані, отримувані від користувача, будуть представлятись моделлю класу `EntryForm` як показано нижче, який
зберігатиметься у файлі `models/EntryForm.php`. Детальніше про присвоєння імен файлам класів читайте в розділі
[Автозавантаження класів](concept-autoloading.md).
10 years ago
```php
<?php
namespace app\models;
use Yii;
10 years ago
use yii\base\Model;
class EntryForm extends Model
{
public $name;
public $email;
public function rules()
{
return [
[['name', 'email'], 'required'],
['email', 'email'],
];
}
}
```
Даний клас успадкований від класу [[yii\base\Model]], який є складовою частиною фреймворку і зазвичай використовується для
роботи з даними форм.
10 years ago
> Info: Клас [[yii\base\Model]] використовується як батьківський клас для класів моделей, які *не* асоційовані з таблицями бази даних.
Клас [[yii\db\ActiveRecord]] зазвичай є батьківським для класів моделей, що відповідають таблицям бази даних.
Клас `EntryForm` містить дві публічні властивості `name` та `email`, які використовуються для зберігання
даних, вказаних користувачем. Він також містить метод `rules()`, який повертає набір
правил перевірки даних. Правила перевірки, оголошені у вищезазначеному коді означають наступне:
10 years ago
* поля `name` і `email` обов’язкові для заповнення;
* поле `email` повинно містити правильну адресу електронної пошти.
10 years ago
Якщо об’єкт `EntryForm` заповнений даними користувача, то для їх перевірки ви можете викликати метод
цього об’єкту [[yii\base\Model::validate()|validate()]]. У випадку
невдалої перевірки властивість [[yii\base\Model::hasErrors|hasErrors]] дорівнюватиме `true`.
За допомогою [[yii\base\Model::getErrors|errors]] можна дізнатись, які саме помилки перевірки виникли.
10 years ago
```php
<?php
$model = new EntryForm();
$model->name = 'Qiang';
$model->email = 'bad';
if ($model->validate()) {
// Все добре!
} else {
// Невдача!
// Використовуйте $model->getErrors()
}
```
10 years ago
Створення дії <span id="creating-action"></span>
-------------
10 years ago
Далі необхідно створити дію `entry` в контролері `site`, яка буде використовувати нову модель. Процес
створення та використання дій описано у розділі [Говоримо "Привіт"](start-hello.md).
10 years ago
```php
<?php
namespace app\controllers;
use Yii;
use yii\web\Controller;
use app\models\EntryForm;
class SiteController extends Controller
{
// ...наявний код...
10 years ago
public function actionEntry()
{
$model = new EntryForm();
10 years ago
if ($model->load(Yii::$app->request->post()) && $model->validate()) {
// дані в $model успішно перевірені
10 years ago
// тут робимо щось корисне з $model ...
10 years ago
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()]].
> Info: `Yii::$app` являє собою глобально доступний екземпляр-одинак [додатка](structure-applications.md)
(singleton). Одночасно це є [Service Locator](concept-service-locator.md), який
надає компоненти, типу `request`, `response`, `db` і так далі для доступу до специфічної функціональності.
У вищезазначеному коді для доступу до даних з `$_POST` був використаний компонент екземпляру додатка `request`.
10 years ago
Якщо все гаразд, дія зобразить представлення `entry-confirm`, яке покаже користувачу вказані ним дані.
Якщо дані не передані або містять помилки, буде зображено представлення `entry` з
HTML-формою та повідомленнями про присутні помилки перевірки даних.
10 years ago
> Note: У цьому дуже простому прикладі ми просто відобразили сторінку підтвердження відправлення даних. На практиці,
ви повинні розглянути використання [[yii\web\Controller::refresh()|refresh()]] або [[yii\web\Controller::redirect()|redirect()]]
для уникнення [проблеми повторного відправлення даних форми](http://en.wikipedia.org/wiki/Post/Redirect/Get).
10 years ago
Створення представлення <span id="creating-views"></span>
-----------------------
10 years ago
На завершення, створюємо два файли представлення з іменами `entry-confirm` і `entry`, котрі зображаються дією `entry`
з минулого підрозділу.
10 years ago
Представлення `entry-confirm` просто зображає ім’я та адресу електронної пошти. Воно мусить бути збережене у файлі `views/site/entry-confirm.php`.
10 years ago
```php
<?php
use yii\helpers\Html;
?>
<p>Ви вказали наступну інформацію:</p>
<ul>
<li><label>Ім’я</label>: <?= Html::encode($model->name) ?></li>
<li><label>Адреса електронної пошти</label>: <?= Html::encode($model->email) ?></li>
10 years ago
</ul>
```
Представлення `entry` відображає HTML-форму. Воно мусить бути збережене у файлі `views/site/entry.php`.
10 years ago
```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-форми представлення використовує потужний [віджет](structure-widgets.md)
[[yii\widgets\ActiveForm|ActiveForm]]. Методи `begin()` і `end()` виводять відкриваючий і закриваючий теги форми
відповідно. Між цими викликами створюються поля для заповнення за допомогою метода
[[yii\widgets\ActiveForm::field()|field()]]. Першим іде поле "name",
другим — "email". Далі для генерування кнопки відправлення даних викликається метод
[[yii\helpers\Html::submitButton()]].
10 years ago
Спробуємо <span id="trying-it-out"></span>
---------
10 years ago
Щоб побачити, як це працює, відкрийте в браузері наступний URL:
10 years ago
```
http://hostname/index.php?r=site%2Fentry
10 years ago
```
Ви побачите сторінку з формою і двома полями для заповнення. Перед кожним полем є надпис, який вказує, яку саме
інформацію слід вказувати. Якщо ви натиснете на кнопку відправлення даних без самих даних або якщо вкажете адресу
електронної пошти в невірному форматі, то ви побачите повідомлення про помилку біля кожного проблемного поля.
10 years ago
![Форма з помилками перевірки](images/start-form-validation.png)
10 years ago
Після введення вірних даних і їх відправлення, ви побачите нову сторінку з даними, які щойно вказали.
10 years ago
![Підтвердження введених даних](images/start-entry-confirmation.png)
10 years ago
### Як працює вся ця "магія" <span id="magic-explained"></span>
10 years ago
Ви можливо здивовані роботою HTML-форми поза лаштунками, тому що може здаватись магічним те, як
зображається підпис до кожного поля та виводяться повідомлення про помилки при некоректному заповненні
й те що все це відбувається без перезавантаження сторінки.
10 years ago
Так, початкова перевірка даних дійсно проходить на стороні клієнта за допомогою JavaScript, і повторно перевіряється
на стороні сервера (PHP). [[yii\widgets\ActiveForm]] достатньо продуманий, щоб взяти правила перевірки, які ви
оголосили в `EntryForm`, перетворити їх в JavaScript код і використовувати його для проведення перевірки.
На випадок, якщо в браузері буде вимкнено JavaScript перевірка проходить і на стороні сервера, як показано в методі
`actionEntry()`. Це дає впевненість в тому, що дані коректні за будь-яких обставин.
10 years ago
> Warning: Перевірка даних на стороні клієнта - це зручність, яка забезпечує краще сприйняття користувачем.
Перевірка на стороні сервера завжди обов’язкова, не зважаючи на клієнтську.
10 years ago
Підписи для полів генеруються методом [[yii\widgets\ActiveForm::field()|field()]], на основі імен властивостей моделі.
Наприклад, підпис `Name` генерується для властивості `name`.
Ви можете модифікувати підписи в межах представлення
наступним чином:
10 years ago
```php
<?= $form->field($model, 'name')->label('Ваше ім’я') ?>
<?= $form->field($model, 'email')->label('Ваша адреса електронної пошти') ?>
10 years ago
```
> Info: У Yii є велика кількість віджетів, які дозволяють швидко будувати складні та динамічні представлення.
Як ви дізнаєтесь пізніше, розробляти нові віджети доволі просто. Багато із представлень можна винести у віджети,
щоб використовувати їх повторно в інших частинах і тим самим спростити розробку в майбутньому.
10 years ago
Підсумок <span id="summary"></span>
--------
10 years ago
В даному розділі ви випробували кожну частину шаблона проектування MVC. Ви дізналися, як
створити клас моделі для репрезентації даних, вказаних користувачем, і як перевіряти ці дані.
10 years ago
Також ви дізналися, як отримувати дані від користувачів та як повертати їх для відображення у браузері. Ця задача може займати
багато часу в процесі розробки. Yii надає потужні віджети, які роблять задачу максимально простою.
10 years ago
В наступному розділі ви дізнаєтесь як працювати з базами даних, що необхідно в більшості додатків.