Робота з базами даних ===================== Цей розділ описує, як створити нову сторінку, яка буде відображати дані країни, отримані з таблиці `country` бази даних. Для цього, вам необхідно буде налаштувати зʼєднання з базою даних, створити клас [Active Record](db-active-record.md), визначити [дію](structure-controllers.md) та створити [представлення](structure-views.md). В даному розділі ви дізнаєтесь як: * налаштувати зʼєднання з базою даних; * визначити клас Active Record; * запитувати дані за допомогою класу Active Record; * відображати дані у представленні із розділенням на сторінки. Зверніть увагу, що для того, щоб закінчити цей розділ, ви повинні мати базові знання і досвід використання баз даних. Зокрема, ви повинні знати, як створювати бази даних та як виконувати SQL-запити за допомогою клієнтських додатків баз даних. Підготовка бази даних --------------------- Для початку, створіть базу даних `yii2basic`, з якої і будете надалі отримувати дані. Ви можете створити базу даних SQLite, MySQL, PostgreSQL, MSSQL або Oracle, Yii має вбудовану підтримку для багатьох баз даних. Для простоти, у подальшому описі будемо вважати що використовується MySQL. Далі, створіть таблицю `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); ``` На даний момент, у вас є база даних `yii2basic` і таблиця `country` з трьома колонками, що містить десять рядків даних. Налаштування підключення до БД ------------------------------ Перш ніж продовжити, переконайтеся, що у вас встановлено розширення PHP [PDO](http://www.php.net/manual/en/book.pdo.php) та драйвер PDO для вашої БД (наприклад `pdo_mysql` для MySQL). Це є основною вимогою, якщо ваш додаток використовує реляційну базу даних. Коли вони встановлені, відкрийте файл `config/db.php` і змініть параметри для відповідності вашій БД. За замовчуванням, файл містить наступне: ```php 'yii\db\Connection', 'dsn' => 'mysql:host=localhost;dbname=yii2basic', 'username' => 'root', 'password' => '', 'charset' => 'utf8', ]; ``` Файл конфігурації `config/db.php` є типовим інструментом [налаштування](concept-configurations.md) на основі файлів. Даний файл конфігурації визначає параметри, які необхідні для створення та ініціалізації екземпляру [[yii\db\Connection]], через який ви можете робити SQL-запити до зазначеної бази даних. З’єднання з БД, описане вище, може бути доступне в коді додатка за допомогою виразу `Yii::$app->db`. > Інформація: Файл конфігурації `config/db.php` буде включений до конфігурації головного додатка `config/web.php`, який визначає як має бути проініціалізований екземпляр [додатку](structure-applications.md). Для отримання додаткової інформації, будь ласка, зверніться до розділу [Конфігурації](concept-configurations.md). Створення Active Record ----------------------- Для презентування та отримання даних з таблиці `country` створіть похідний від [Active Record](db-active-record.md) клас з іменем `Country`, і збережіть його в файл `models/Country.php`. ```php Інформація: Якщо неможливо отримати прямої відповідності імені класу до імені таблиці, ви можете перевизначити метод [[yii\db\ActiveRecord::tableName()]], щоб точно задати відповідне імʼя таблиці. Використовуючи клас `Country`, ви можете легко маніпулювати даними з таблиці `country`, як показано у цих фрагментах коду: ```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). Створення дії ------------- Щоб відобразити дані про країну кінцевим користувачам, необхідно створити нову дію. Замість розміщення нової дії у контролері `site`, який ви використовували в попередніх розділах, є сенс створити новий контролер спеціально для всіх дій, пов’язаних з даними країн. Створіть новий контролер з іменем `CountryController` і дію `index`, як показано нижче: ```php 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` служить двом цілям: * Встановлює директиви `offset` і `limit` для SQL-запиту так, щоб він повертав лише одну сторінку даних за один раз (не більше 5 рядків на сторінці). * Використовується у представленнях для відображення пейджера, який складається із переліку кнопок переходу по сторінках, про що буде описано у наступному підрозділі. Наприкінці, дія `index` формує представлення з іменем `index` та передає до нього дані по країнах із інформацією про посторінкове розділення. Створення представлення ----------------------- В директорії `views` створіть спочатку під-директорію `country`. Цей каталог буде використовуватись для всіх представлень контролера `country`. В директорії `views/country`, створіть файл з іменем `index.php`, що містить наступне: ```php

Країни

$pagination]) ?> ``` Дане представлення містить дві секції для відображення даних про країни. У першій частині, відображаються передані дані про країни у вигляді невпорядкованого списку HTML. У другій частині, віджет [[yii\widgets\LinkPager]] з використанням інформації про нумерацію сторінок. Віджет `LinkPager` відображається у вигляді переліку кнопок. При натисканні на будь-якій з них будуть виводитись дані країн для відповідної сторінки. Спробуємо --------- Щоб побачити як весь вищезазначений код працює, відкрийте в браузері наступний URL: ``` http://hostname/index.php?r=country/index ``` ![Перелік країн](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`. В результаті, будуть відображені перші знайдені пʼять країн. * Віджет [[yii\widgets\LinkPager|LinkPager]] відображає кнопки сторінок з URL-адресами створеними за допомогою [[yii\data\Pagination::createUrl()|Pagination]]. URL-адреси будуть містити параметр запиту `page`, який представляє різні номери сторінок. * Якщо натиснути кнопку "2", новий запит для маршруту `country/index` спрацьовує і обробляється. [[yii\data\Pagination|Pagination]] зчитає параметр `page` з URL-запиту і встановить для поточної сторінки номер 2. Таким чином, новий запит до БД буде мати умову `LIMIT 5 OFFSET 5` і поверне наступні пʼять країн для відображення. Підсумок -------- В цьому розділі ви дізналися, як працювати з базою даних. Ви також дізналися, як вибирати і відображати дані на сторінках за допомогою [[yii\data\Pagination]] і [[yii\widgets\LinkPager]]. У наступному розділі ви дізнаєтеся, як використовувати потужний інструмент генерації коду, що називається [Gii](https://github.com/yiisoft/yii2-gii/blob/master/docs/guide-uk/README.md), який допоможе вам швидко створювати деякі часто необхідні функції, такі як Create-Read-Update-Delete (CRUD) операції для роботи з даними в таблицях баз даних. Насправді, код, який ви щойно написали, в Yii можливо автоматично згенерувати за допомогою інструменту Gii.