start-databases.md 14.9 KB
Newer Older
RichWeber committed
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
Робота з базами даних
======================

Цей розділ описує, як створити нову сторінку, яка буде відображати назву країни, отриману з таблиці бази даних `country`. Для досягнення цієї мети, вам необхідно буде налаштувати з'єднання з базою даних, отримати необхідні дані з допомогою класу [Active Record](db-active-record.md), створити [подію](structure-controllers.md),
і зобразити все в [представленні](structure-views.md).

З допомогою даного посібника ви дізнаєтесь як:

* Налаштувати з’єднання з базою даних
* Оголосити Active Record класс
* Створювати запити використовуючи Active Record клас
* Відображати дані в представленні з нумерацією сторінок

Зверніть увагу, що для того, щоб закінчити цей розділ, ви повинні мати базові знання і досвід використання баз даних. Зокрема, ви повинні знати, як створювати бази даних, як виконувати SQL-запити , використовуючи клієнти баз даних.


Підготовка бази даних <a name="preparing-database"></a>
--------------------

Для початку створіть базу даних `yii2basic`, з якої і будете надалі отримувати дані. Ви можете використовувати SQLite, MySQL, PostgreSQL, MSSQL або Oracle бази даних, Yii має вбудовану підтримку для багатьох баз даних.

Далі, створіть таблицю `country`, і внесіть декілька прикладів. Можете використати наступний SQL-запит, як приклад:

```sql
CREATE TABLE `country` (
  `code` CHAR(2) NOT NULL PRIMARY KEY,
  `name` CHAR(52) NOT NULL,
  `population` INT(11) NOT NULL DEFAULT '0'
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO `country` VALUES ('AU','Australia',18886000);
INSERT INTO `country` VALUES ('BR','Brazil',170115000);
INSERT INTO `country` VALUES ('CA','Canada',1147000);
INSERT INTO `country` VALUES ('CN','China',1277558000);
INSERT INTO `country` VALUES ('DE','Germany',82164700);
INSERT INTO `country` VALUES ('FR','France',59225700);
INSERT INTO `country` VALUES ('GB','United Kingdom',59623400);
INSERT INTO `country` VALUES ('IN','India',1013662000);
INSERT INTO `country` VALUES ('RU','Russia',146934000);
INSERT INTO `country` VALUES ('US','United States',278357000);
```

RichWeber committed
43
На даний момент, у вас є база даних `yii2basic` і таблиця `country` з трьома колонками, що містять десять рядків даних.
RichWeber committed
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63

Налаштування підключення до БД <a name="configuring-db-connection"></a>
---------------------------

Перш ніж продовжити, переконайтеся, що у вас налаштовано [PDO](http://www.php.net/manual/en/book.pdo.php) PHP розширення і PDO драйвер для вашої БД (наприклад `pdo_mysql` для MySQL). Це є основною вимогою якщо ваш додаток використовує реляційну базу даних.

Згідно того, що у вас встановлено, відкрийте файл `config/db.php` і замініть на коректні дані вашої БД. За замовчуванням, файл містить наступне:

```php
<?php

return [
    'class' => 'yii\db\Connection',
    'dsn' => 'mysql:host=localhost;dbname=yii2basic',
    'username' => 'root',
    'password' => '',
    'charset' => 'utf8',
];
```

RichWeber committed
64
Файл конфігурації `config/db.php`  є типовим інструментом на основі файлів [налаштування](concept-configurations.md). Даний файл конфігурації визначає параметри, які необхідні для створення і ініціалізації [[yii\db\Connection]] примірника, через який ви можете робити SQL-запити до основної бази даних.
RichWeber committed
65

RichWeber committed
66
З’єднання з БД описане вище може бути доступне в коді програми за допомогою виразу `Yii::$app->db`.
RichWeber committed
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

> Інформація: Файл конфігурації `config/db.php` буде включений до конфігурації головного додатка `config/web.php`, який визначає як має бути проініційований сам [додаток](structure-applications.md).
  Для отримання додаткової інформації, будь ласка, зверніться до розділу [Налаштування](concept-configurations.md).


Створення Active Record <a name="creating-active-record"></a>
-------------------------

Для відображення і отримання даних з таблиці `country` створіть [Active Record](db-active-record.md) клас з іменем `Country`, і збережіть в файл `models/Country.php`.

```php
<?php

namespace app\models;

use yii\db\ActiveRecord;

class Country extends ActiveRecord
{
}
```

Клас `Country` наслідує [[yii\db\ActiveRecord]]. Вам не потрібно писати ніякого коду всередині нього! Всього лише за допомогою описаного вище коду, 
Yii отримає відповідне ім'я таблиці з імені класу.

RichWeber committed
92
> Інформація: Якщо немає прямого співпадіння з імені класу і таблиці, ви можете використати метод [[yii\db\ActiveRecord::tableName()]] щоб задати відповідне ім'я таблиці.
RichWeber committed
93

RichWeber committed
94
Використовуючи клас `Country`, ви можете легко маніпулювати даними з таблиці `country`, як показано в наступному фрагменті:
RichWeber committed
95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118

```php
use app\models\Country;

// отримати всі рядки з таблиці country і замовити їх по "name"
$countries = Country::find()->orderBy('name')->all();

// отримати рядок, по основному ключу "US"
$country = Country::findOne('US');

// відобразити "United States"
echo $country->name;

// оновити назву країни на "U.S.A." і зберегти в БД
$country->name = 'U.S.A.';
$country->save();
```

> Інформація: Active Record є потужним засобом для доступу і управління даними в базі даних в об'єктно-орієнтованому стилі. Ви можете знайти більш детальну інформацію в розділі [Active Record](db-active-record.md). Крім того, ви також можете взаємодіяти з базою даних, використовуючи для доступу метод передачі даних нижнього рівня під назвою [Data Access Objects](db-dao.md).


Створення події <a name="creating-action"></a>
------------------

RichWeber committed
119
Щоб відобразити дані про країну кінцевим користувачам, необхідно створити нову подію. Замість розміщення нової події в контролері `site`, який ви використовували в попередніх розділах, є сенс створити новий контролер спеціально для всіх подій пов’язаних з даними таблиці країн. Створіть навий контролер з іменем `CountryController` і подію `index`, як показано нижще.
RichWeber committed
120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215

```php
<?php

namespace app\controllers;

use yii\web\Controller;
use yii\data\Pagination;
use app\models\Country;

class CountryController extends Controller
{
    public function actionIndex()
    {
        $query = Country::find();

        $pagination = new Pagination([
            'defaultPageSize' => 5,
            'totalCount' => $query->count(),
        ]);

        $countries = $query->orderBy('name')
            ->offset($pagination->offset)
            ->limit($pagination->limit)
            ->all();

        return $this->render('index', [
            'countries' => $countries,
            'pagination' => $pagination,
        ]);
    }
}
```

Збережіть цей код у файл `controllers/CountryController.php`.

Подія `index` викликає метод `Country::find()`. Цей Active Record метод будує запит і отримує всі дані з таблиці `country`.
Щоб обмежити кількість країн, які будуть отримуватись в кожному запиті, сам запит розбивається на сторінки, за допомогою 
[[yii\data\Pagination]] об'єкта. Об’єкт `Pagination` служить двом цілям:

* Встановлює `положення` і `ліміт` для SQL-запиту так, щоб він повертав лише одну сторінку даних за один раз (не більше 5 рядків в сторінці).
* Використовується в цілях відображення пейджера, що складається зі списку кнопок сторінок, як буде описано в наступному підрозділі.

Наприкінці, подія `index` повертає представлення `index` і передає дані по країнах, з розбивкою на сторінки.


Створення представлення <a name="creating-view"></a>
---------------

В директорії `views` створіть спочатку підкаталог `country`. Цей каталог буде використовуватись для всіх представленнь контролера `country`. В каталозі `views/country`, створіть файл з іменем`index.php` 
що містить наступне:

```php
<?php
use yii\helpers\Html;
use yii\widgets\LinkPager;
?>
<h1>Країни</h1>
<ul>
<?php foreach ($countries as $country): ?>
    <li>
        <?= Html::encode("{$country->name} ({$country->code})") ?>:
        <?= $country->population ?>
    </li>
<?php endforeach; ?>
</ul>

<?= LinkPager::widget(['pagination' => $pagination]) ?>
```

Дане представлення містить два розділи для відображення даних по країнам. У першій частині, відображаються дані про країни у вигляді невпорядкованого списку HTML. У другій частині, [[yii\widgets\LinkPager]] віджет з використанням інформації про нумерацію сторінок.
`LinkPager` віджет показується у вигляді списку кнопок. При натисканні на будь-якій з них будуть оновлюватись дані країн у відповідній сторінці.


Спробуєм <a name="trying-it-out"></a>
-------------

Щоб побачити все, що було створено під час роботи, відкрийте в браузері наступний URL:

```
http://hostname/index.php?r=country/index
```

![Перелік країн](../guide/images/start-country-list.png)

Спочатку, ви побачите сторінку з переліком п'яти країн. Нижче країн, ви побачите пейджер з чотирма кнопками. 
Якщо ви натиснете на кнопку "2", ви побачите сторінку ще п'ять країн з бази даних: другу сторінку записів. 
Придивившись більш уважно, ви побачите, що URL в браузері також змінюється на

```
http://hostname/index.php?r=country/index&page=2
```

За лаштунками, [[yii\data\Pagination|Pagination]] надає всю необхідну функціональність для розбивки набору даних на сторінки:

* Спочатку, [[yii\data\Pagination|Pagination]] представляє першу сторінку, яка відображає країни запитом SELECT з умовою `LIMIT 5 OFFSET 0`. В результаті, будуть відображені перші знайдені п'ять країн.
RichWeber committed
216 217
* [[yii\widgets\LinkPager|LinkPager]] віджет відображає кнопки сторінок з URL-адресами створеними за допомогою [[yii\data\Pagination::createUrl()|Pagination]]. URL-адреси будуть містити параметр запиту `page`, який представляє різні номери сторінок.
* Якщо ви натиснете кнопку "2", спрацює новий запит, який буде відправлений на `country/index` з подальшим опрацюванням.
RichWeber committed
218 219 220 221 222 223 224 225 226
  [[yii\data\Pagination|Pagination]] зчитає параметр `page` з URL-запиту і встановить номер поточної сторінки в 2-ку.
  Таким чином, новий запит буде мати пункт `LIMIT 5 OFFSET 5` і поверне наступні п'ять країн для відображення.


Резюме <a name="summary"></a>
-------

В цьому розділі ви дізналися, як працювати з базою даних. Ви також дізналися, як вибирати і відображати дані на сторінках за допомогою [[yii\data\Pagination]] і [[yii\widgets\LinkPager]].

RichWeber committed
227
У наступному розділі ви дізнаєтеся, як використовувати потужний інструмент генерації коду, що називається [Gii](tool-gii.md), який допоможе вам швидко здійснювати деякі часто необхідні функції, такі як Create-Read-Update-Delete (CRUD) операції для роботи з даними в таблицях баз даних. Насправді, код, який ви щойно написали, Yii може автоматично сгенерувати з допомогою функції Gii.