Yii 2.0 часть 2. Работа с базами данных
Yii 2.0. конспект-памятка курса 'Полное руководство по Yii 2.0' с незначительными вариациями. Оригинал на русском языке можно найти здесь.
АЛАРМА!!! Данная памятка являет собой откровенный копипаст! Для ознакомления с первоисточником перейдите по ссылке, указанной выше.
копипастил Капустин Яков
оглавление
01Создание базы данных
Создадим новую страницу, отображающую данные по странам, полученные из таблицы countries базы данных (необходимо настроить подключение к базе данных, создать класс Active Record, определить action и создать view).
Подготовка базы данных
Для начала создадим базу данных под названием yii2basic, используя MySQL.
- Переходим в phpmyadmin;
- Создаём новую базу данных yii2basic, указав ей сравнение utf8_unicode_ci;
- Создаём в базе данных таблицу country;
- Переходим на вкладку SQL;
- Вставляем представленный ниже код запроса и выполняем его
- Теперь мы имеем базу данных yii2basic с таблицей country с тремя столбцами, содержащими десять строк данных.
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
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',24016400);
INSERT INTO `country` VALUES ('BR','Brazil',205722000);
INSERT INTO `country` VALUES ('CA','Canada',35985751);
INSERT INTO `country` VALUES ('CN','China',1375210000);
INSERT INTO `country` VALUES ('DE','Germany',81459000);
INSERT INTO `country` VALUES ('FR','France',64513242);
INSERT INTO `country` VALUES ('GB','United Kingdom',65097000);
INSERT INTO `country` VALUES ('IN','India',1285400000);
INSERT INTO `country` VALUES ('RU','Russia',146519759);
INSERT INTO `country` VALUES ('US','United States',322976000);
Настраиваем подключение к БД
Я верю, что у меня установлены PHP-расширение PDO и драйвер PDO для используемой базы данных (pdo_mysql для MySQL),по этому просто открываю файл config/db.php и проверяю параметры базы данных:
02
03
04
05
06
07
08
09
10
11
12
13
14
15
return [
'class' => 'yii\db\Connection',
'dsn' => 'mysql:host=localhost;dbname=yii2basic',
'username' => 'root',
'password' => '****',
'charset' => 'utf8',
// Schema cache options (for production environment)
//'enableSchemaCache' => true,
//'schemaCacheDuration' => 60,
//'schemaCache' => 'cache',
];
Подключение к БД, настроенное выше, доступно в коде приложения через выражение Yii::$app->db. Файл config/db.php будет подключен главной конфигурацией приложения config/web.php, описывающей то, как экземпляр приложения должен быть инициализирован.
Создаём потомка Active Record
Чтобы представлять и получать данные из таблицы country, в файле models/Country.php создадим класс Country — потомок Active Record. Yii сам свяжет имя таблицы с именем класса. Если нет возможности задать прямую зависимость между именем таблицы и именем класса, можно переопределить метод yii\db\ActiveRecord::tableName(), чтобы явно задать имя связанной таблицы.
2
3
4
5
6
7
8
9
namespace app\models;
use yii\db\ActiveRecord;
class Country extends ActiveRecord{
}
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
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();
02Создание нового контроллера
Для того, чтобы показать данные по странам конечным пользователям, необходимо создать новый action. В данном случае вместо размещения нового action'a в контроллере site, будет иметь больше смысла создать новый контроллер - специально для всех действий, относящихся к данным по странам.
Создние Action
Создадим новый контроллер CountryController, и action index внутри него.
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
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,
// ]);
// упростим передачу массива в вид, используя функцию compact()
return $this->render('index', compact('countries','pagination'));
}
}
Action index вызывает Country::find(). Данный метод Active Record строит запрос к БД и извлекает все данные из таблицы country. Чтобы ограничить количество стран, возвращаемых каждым запросом, запрос разбивается на страницы с помощью объекта yii\data\Pagination. Объект Pagination служит двум целям:
- Устанавливает пункты offset и limit для SQL инструкции, представленной запросом, чтобы она возвращала только одну страницу данных за раз (в нашем случае максимум 5 строк на страницу);
- Используется во view для отображения пагинатора, состоящего из набора кнопок с номерами страниц, это будет разъяснено в следующем подразделе.
В конце кода action index выводит view с именем index, и передаёт в него данные по странам вместе c информацией о пагинации.
Создаём View
Первым делом необходимо создать поддиректорию с именем контроллера (в данном случае имя контроллера CountryController - стало быть поддиректорию следует назвать country) внутри директории views. Эта папка будет использоваться для хранения всех view, выводимых контроллером country. Затем внутри директории views/country создадим файл с именем index.php, содержащий следующий код:
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
use yii\helpers\Html;
use yii\widgets\LinkPager;
$res="<h1>Страны</h1><ol>";
foreach($countries as $country){
$res.="<li>Код страны: ".
Html::encode("{$country->code} ({$country->name})") .
"; население: ".
$country->population .
";</li>";
}
$res.="</ol>";
$res.=LinkPager::widget(compact('pagination'));
echo $res;
unset($res);
Проверка
Чтобы увидеть, как работает весь вышеприведённый код, перейдите по следующей ссылке в своём браузере: /index.php?r=country%2Findex.
За кадром Pagination предоставляет всю необходимую функциональность для постраничной разбивки набора данных:
- В начале Pagination показывает первую страницу, которая отражает SELECT запрос стран с параметрами LIMIT 5 OFFSET 0. Как результат, первые пять стран будут получены и отображены;
- Виджет LinkPager выводит кнопки страниц используя URL'ы, созданные Pagination. Эти URL'ы будут содержать параметр запроса page, который представляет различные номера страниц;
- Если вы кликните по кнопке '2', сработает и обработается новый запрос для маршрута country/index. Таким образом новый запрос стран будет иметь параметры LIMIT 5 OFFSET 5 и вернет следующие пять стран для отображения.
Капустин Яков (2019.01.23 22:13)