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