В данной статье мы узнаем как выбирать данные
из базе данных.
Для более глубокого понимания рекомендую пройти платный курс по Yii2 от команды WebForMySelf. Для ознакомления есть и бесплатная часть.
Что нам необходимо для работы с базой данных?
- Сама база данных (ссылка на скачивание исходника).
- Подключение к ней.
- Метод который позволит выбирать данные.
Как подключаться к базе данных в Yii2?
Использовать будем эту базу.
Подключение настраивается в файле /config/db.php, вот что содержит у меня данный файл:
1 2 3 4 5 6 7 8 |
<?php return [ 'class' => 'yii\db\Connection', 'dsn' => 'mysql:host=localhost;dbname=yii2', 'username' => 'root', 'password' => '', 'charset' => 'utf8', ]; |
Создаём класс для работы с базой данных
1 2 3 4 5 6 7 8 |
<?php namespace app\models; // подключаем пространство имён use yii\db\ActiveRecord; // подключаем класс ActiveRecord class Сategories extends ActiveRecord // расширяем класс ActiveRecord { } |
Чтение данных из базе данных, операция read
Метод чтения данных в Yii 2 является метод find, и ряд других методов класса activeRecord. Наша модель должна расширять данный класс.
Теперь нашу модель Мы должны использовать в контроллере:
1 2 3 |
// тут наш контроллер $cats = Сategories::find()->all(); // дальше идёт контроллер |
Обратите внимание что если Вы используете модель в контроллере, то должны её подключать. В нашем случае это будет:
1 |
use app\models\Сategories; |
Наша строка $cats = Category::find()->all(); делает то же самое что и данный SQL запрос
1 |
SELECT * FROM `categories` |
Результат:
Теперь важный момент: если Мы называем модель по имени таблицы, тогда фреймворк автоматически свяжет модель с соответствующей таблицей.
Что делать если у нас таблица называется по разному от модели?
Сделать это можно с помощью статического метода tableName:
1 2 3 4 5 6 7 8 9 |
<?php class Category extends ActiveRecord { public static function tableName() { return "categories"; // тут меняем таблицу с которой будет работать модель } } ?> |
Пройтись в цикле по результатам выборки
можно следующим образом:
1 2 3 4 5 6 |
<?php foreach ($cats AS $cat): echo $cat->title; echo "<br>"; endforeach; ?> |
Результат будет следующий:
Как выбрать только часть данных
Часто бывает что нам нужны не все данные а только часть из них, поэтому давайте рассмотрим как можно выбрать данные по условию.
Выборка будет разбиваться на 3 шага:
- Создадим новый объект запроса. (этим занимается метод find)
- Настроим объект запроса, который создали в шаге №1. (за это отвечают методы строения запросов)
- Получение данных в виде объекта.
Межу первым и последним шагом могут находиться много методов которые будут настраивать запрос.
Как сортировать данные в запросе:
1 2 3 |
$cats = Category::find()->orderBy(['id' => SORT_ASC])->all(); // или $cats = Category::find()->orderBy(['id' => SORT_DESC])->all(); |
Как вытащить данные в виде массива (array) а не объекта:
Это может быть полезно когда вытаскиваются большое количество данных. Документация Yii рекомендует в таком случае выбирать данные в виде массива. Потому что массив потребляет меньше ресурсов.
1 |
$cats = Category::find()->asArray()->all(); |
Результат:
Метод которые позволяет задавать условия (where):
1 |
$cats = Category::find()->where('parent = 691')->all(); |
Есть ещё вариант передачи параметров в метод where это массив:
1 |
$cats = Category::find()->where(['parent' => 691])->all(); |
Теперь давайте рассмотрим пример использования оператора LIKE:
1 2 3 4 |
$cats = Category::find()->where(['like', 'title', 'pp'])->all(); // Маркеры в виде %pp% писать не нужно. // запрос в SQL выглядел бы так: // SELECT * FROM `categories` WHERE `title` LIKE '%pp%' |
И ещё один пример запроса:
1 2 3 |
// Выберем данные где поле `id` меньше или ровно 695 $cats = Category::find()->where(['<=', 'id', 695])->all(); // Запрос: SELECT * FROM `categories` WHERE `id` <= 695 |
Как вытащить только один ряд из базе данных:
Это можно делать двумя способами:
1. Использование оператора limit:
1 2 |
$cats = Category::find()->where(['parent' => 691])->limit(1)->all(); // Запрос: SELECT * FROM `categories` WHERE `parent`=691 LIMIT 1 |
В результате создаётся многомерный массив.
2. Использование метода one:
1 2 |
$cats = Category::find()->where(['parent' => 691])->one(); // Запрос: SELECT * FROM `categories` WHERE `parent`=691 |
В результате создаётся одномерный массив.
Рекомендую:
Даже если вы используете метод one всегда добавляйте limit чтоб ограничить выборку только одной записью.
Как считать данные (использование оператора count):
1 2 |
$cats = Category::find()->where(['<=', 'id', 695])->count(); // Запрос: SELECT COUNT(*) FROM `categories` WHERE `id` <= 695 |
Так-же мы можем использовать и другие методы, например SUM чтобы суммировать, и.т.д.
Как писать свой SQL запросы в Yii2 без использования методов:
1 2 |
$query = "SELECT * FROM `categories` WHERE `title` LIKE '%pp%'"; $cats = Category::findBySql($query)->all(); |
Использовать такой вариант не совсем правильно потому что у нас pp это часто данные которые приходят к нам от пользовательской части сайта, например из формы поиска, и что пользователь там введёт мы не знаем, это могут быть SQL инъекций или что-то ещё. В этом случае рекомендуется использовать параметризированный запрос который при выполнение будет экранирован. Вот пример:
1 2 |
$query = "SELECT * FROM `categories` WHERE `title` LIKE :search"; $cats = Category::findBySql($query, [':search' => '%pp%'])->all(); |
Удачной использование MySQL в Yii 😉
Огромное спасибо за статью! А-то столкнулся со случаем, когда название таблиц в БД конфликтовало с политикой имён yii2. В мануале не сказано про случай, когда названия таблицы и класса отличаются.
Указано https://yiiframework.com.ua/ru/doc/guide/2/db-active-record/#nastrojka-imeni-tablicy
Пожалуйста.
Рад что статья оказалась полезной.