Построитель запросов
Построитель запросов (Query Builder) собирает запрос SQL из вызовов методов и сам экранирует значения. Он нужен там, где методов модели не хватает: для соединения таблиц, подсчётов, массовых изменений. Отдельного файла для него нет — построитель вызывают в контроллере или в методе модели.
Первая выборка
// app/Controllers/Posts.php
public function titles()
{
$db = db_connect();
$rows = $db->table('posts')
->select('id, title')
->get()
->getResultArray();
return $this->response->setJSON($rows);
}table() начинает запрос к таблице, select() перечисляет столбцы, get() выполняет запрос, а getResultArray() возвращает строки массивами. С маршрутом $routes->get('titles', 'Posts::titles'); адрес /titles покажет список идентификаторов и заголовков в формате JSON.
| Метод результата | Что возвращает |
|---|---|
getResultArray() | Все строки массивами |
getResult() | Все строки объектами |
getRowArray() | Одну строку |
countAllResults() | Число строк (вместо get()) |
Условия и сортировка
$rows = $db->table('posts')
->where('status', 1)
->like('title', 'php')
->orderBy('created_at', 'DESC')
->limit(10)
->get()
->getResultArray();Запрос вернёт десять последних опубликованных статей, в заголовке которых есть «php». Несколько where() соединяются через AND.
| Метод | Что добавляет |
|---|---|
where('views >', 100) | Сравнение: оператор пишут вместе с именем столбца |
orWhere('status', 2) | Условие через OR |
whereIn('id', [1, 2, 3]) | Значение из списка |
like('title', 'php') | Поиск по части строки |
orderBy('id', 'DESC') | Сортировку |
limit(10, 20) | Десять строк, пропустив двадцать |
Соединение таблиц
Допустим, есть таблица comments со столбцом post_id. Число комментариев к каждой статье считает один запрос:
$rows = $db->table('posts')
->select('posts.id, posts.title, COUNT(comments.id) AS total')
->join('comments', 'comments.post_id = posts.id', 'left')
->groupBy('posts.id')
->get()
->getResultArray();Третий аргумент join() — тип соединения: с left в результат попадут и статьи без комментариев.
Те же методы в модели
Модель построена на построителе, поэтому его методы вызывают прямо у неё и завершают привычным findAll():
$posts = model(PostModel::class)
->where('status', 1)
->orderBy('created_at', 'DESC')
->findAll(10);Для запросов к одной таблице этот способ короче.
Вставка, изменение, удаление
$db->table('posts')->insert(['title' => 'Статья', 'body' => 'Текст']);
$db->table('posts')->where('id', 5)->update(['status' => 1]);
$db->table('posts')->where('status', 0)->delete();В отличие от модели, построитель не проверяет $allowedFields и не заполняет даты.
Запрос SQL с параметрами
$rows = $db->query('SELECT * FROM posts WHERE status = ? AND id > ?', [1, 10])
->getResultArray();Значения передаются вторым аргументом и подставляются на место знаков вопроса уже экранированными.
Частая ошибка
Значение, вклеенное в текст запроса, — $db->query("SELECT * FROM posts WHERE title = '$title'") — открывает путь SQL-инъекции: посетитель сможет дописать к запросу свой код. Используйте методы построителя или знаки вопроса с массивом значений.