Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Оглавление

Построение запросов

Метод find() возвращает объект запроса. К нему по цепочке добавляют условия, сортировку и ограничения, а в конце вызывают метод, который выполняет запрос. Отдельных файлов для запросов нет: их пишут в контроллерах и моделях.

Простой запрос

$posts = Post::find()
    ->where(['status' => 1])
    ->all();

Запрос вернёт массив объектов Post — все статьи со статусом 1. В базу уйдёт SELECT * FROM post WHERE status = 1.

Сортировка и ограничение

$latest = Post::find()
    ->where(['status' => 1])
    ->orderBy(['created_at' => SORT_DESC])
    ->limit(10)
    ->all();

Получится десять самых новых опубликованных статей. SORT_DESC — по убыванию, SORT_ASC — по возрастанию.

Виды условий

ЗаписьЧто означает
['status' => 1, 'user_id' => 5]Оба равенства сразу
['id' => [1, 2, 3]]Значение из списка
['>', 'created_at', 1767225600]Сравнение
['like', 'title', 'php']Заголовок содержит слово
['between', 'id', 10, 20]Значение в диапазоне
['not', ['slug' => '']]Отрицание условия

Значения в таких условиях Yii подставляет безопасно сам.

Составные условия

Условия добавляют методами andWhere() и orWhere() — это удобно, когда часть из них зависит от запроса посетителя:

// controllers/PostController.php
public function actionSearch(string $q = ''): string
{
    $query = Post::find()->where(['status' => 1]);
 
    if ($q !== '') {
        $query->andWhere(['like', 'title', $q]);
    }
 
    return $this->render('index', ['posts' => $query->all()]);
}

Адрес /post/search?q=yii покажет опубликованные статьи со словом «yii» в заголовке, а без параметра — все опубликованные.

Чем заканчивается запрос

МетодЧто возвращает
all()Массив объектов
one()Первый объект или null
count()Количество строк
exists()true, если есть хотя бы одна строка
column()Значения первого выбранного столбца

Метод asArray() перед all() возвращает строки обычными массивами — это быстрее на больших выборках: Post::find()->select(['id', 'title'])->asArray()->all().

Построитель без модели

Для отчётов модели не нужны — подойдёт класс Query:

use yii\db\Query;
 
$rows = (new Query())
    ->select(['user_id', 'total' => 'COUNT(*)'])
    ->from('post')
    ->groupBy('user_id')
    ->all();

Результат — массив строк с числом статей каждого автора.

Транзакции

Транзакция объединяет несколько изменений: либо выполнятся все, либо ни одно.

Yii::$app->db->transaction(function () use ($post, $comment) {
    $post->save();
    $comment->post_id = $post->id;
    $comment->save();
});

Если внутри функции возникнет исключение, все изменения отменятся.

Частая ошибка

Условие, собранное строкой из данных посетителя, — where("title = '$q'") — открывает путь SQL-инъекции: посетитель сможет дописать в запрос свой код. Используйте запись массивом или параметры: where('title = :title', [':title' => $q]).

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.