Робота з базами даних

Цей розділ описує, як створити нову сторінку, яка буде відображати дані країни, отримані з таблиці бази даних country. Для цього, вам необхідно буде налаштувати зʼєднання з базою даних, створити клас Active Record, визначити дію та створити представлення.

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

  • Налаштувати зʼєднання з базою даних
  • Оголосити Active Record класс
  • Запитувати дані за допомогою класу Active Record
  • Відображати дані у представленні із розбиттям по сторінках

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

Підготовка бази даних

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

Далі, створіть таблицю country, і внесіть декілька прикладів. Можете використати наступний 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 з трьома колонками, що містять десять рядків даних.

Налаштування підключення до БД

Перш ніж продовжити, переконайтеся, що у вас налаштовано PDO PHP розширення і PDO драйвер для вашої БД (наприклад pdo_mysql для MySQL). Це є основною вимогою, якщо ваш додаток використовує реляційну базу даних.

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

<?php

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

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

З’єднання з БД, описане вище, може бути доступне в коді додатка за допомогою виразу Yii::$app->db.

Інформація: Файл конфігурації config/db.php буде включений до конфігурації головного додатка config/web.php, який визначає як має бути проініційований сам додаток. Для отримання додаткової інформації, будь ласка, зверніться до розділу Налаштування.

Створення Active Record

Для відображення і отримання даних з таблиці country створіть Active Record клас з іменем Country, і збережіть в файл models/Country.php.

<?php

namespace app\models;

use yii\db\ActiveRecord;

class Country extends ActiveRecord
{
}

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

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

Використовуючи клас Country, ви можете легко маніпулювати даними з таблиці country, як показано в наступному фрагменті:

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. Крім того, ви також можете взаємодіяти з базою даних, використовуючи для доступу метод передачі даних нижнього рівня під назвою Data Access Objects.

Створення дії

Щоб відобразити дані про країну кінцевим користувачам, необхідно створити нову дію. Замість розміщення нової дії у контролері site, який ви використовували в попередніх розділах, є сенс створити новий контролер спеціально для всіх дій, пов’язаних з даними країн. Створіть новий контролер з іменем CountryController і дію index, як показано нижче:

<?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 служить двом цілям:

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

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

Створення представлення

В директорії views створіть спочатку підкаталог country. Цей каталог буде використовуватись для всіх представленнь контролера country. В каталозі views/country, створіть файл з іменемindex.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 відображаться у вигляді переліку кнопок. При натисканні на будь-якій з них будуть оновлюватись дані країн на відповідній сторінці.

Спробуєм

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

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

Перелік країн

Спочатку, ви побачите сторінку з переліком пʼяти країн. Нижче країн, ви побачите пейджер з чотирма кнопками. Якщо ви натиснете на кнопку "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, який допоможе вам швидко здійснювати деякі часто необхідні функції, такі як Create-Read-Update-Delete (CRUD) операції для роботи з даними в таблицях баз даних. Насправді, код, який ви щойно написали, Yii може автоматично сгенерувати з допомогою функції Gii.