> For the complete documentation index, see [llms.txt](https://docs.johncms.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.johncms.com/10.0/baza-dannykh/vypolnenie-zaprosov-k-baze-dannykh.md).

# Выполнение запросов к базе данных

На данный момент в JohnCMS доступны несколько вариантов выполнения запросов к базе данных.

## **PDO**

Этот вариант многим известен и применяется ещё с JohnCMS 7.0.\
Давайте рассмотрим особенности использования этого варианта.\
Чтобы получить объект PDO нам достаточно написать следующий код:

```php
$db = di(PDO::class);
```

Далее используя объект **$db** вы можете выполнять запросы к базе данных.\
Рассмотрим пример, который получает записи из таблицы users:

```php
$db = di(PDO::class);
$req = $db->query('SELECT * FROM `users`');
while ($row = $req->fetch()) {
    echo $row['name'] .'
';
}
```

Этот пример выведет список имен пользователей, которые есть в таблице users.

{% hint style="danger" %}
**Обратите внимание**\
При работе с этим вариантом вы должны самостоятельно заботиться о безопасности запросов.
{% endhint %}

## **Конструктор запросов (Query Builder)**

В JohnCMS для работы с БД используется библиотека [illuminate/database](https://github.com/illuminate/database) которая и предоставляет конструктор запросов и ORM.\
Рассмотрим несколько основных примеров чтобы понять особенности работы с библиотекой в JohnCMS.

Для выполнения запросов, сначала нам необходимо получить объект текущего подключения к БД:

```php
$connection = \Illuminate\Database\Capsule\Manager::connection();
```

\
Далее давайте выполним тот же запрос, который выполняли в обычном PDO варианте выше.

```php
$users = $connection->table('users')->get();
foreach ($users as $user) {
    echo $user->name . '<br>';
}
```

Этот запрос так же как и в предыдущем варианте выведет список имен пользователей, которые есть в таблице users.\
Метод **get** возвращает объект **Illuminate\Support\Collection** c результатами, в котором каждый результат — это экземпляр PHP-класса **StdClass**. Вы можете получить значение каждого столбца, обращаясь к столбцу как к свойству объекта.\
Давайте рассмотрим вариант получения одной строки из таблицы.

```php
$user = $connection->table('users')->where('name', 'admin')->first();
echo $user->name;
```

Этот запрос вернет пользователя, у которого поле **name** равно **admin**.

Рассмотрим вариант вывода записей из таблицы с разбивкой на страницы по 5 элементов.\
Метод **paginate** конструктора запросов в JohnCMS не используется: постраничную навигацию строит сервис `PaginationFactory`, а запрос получает явные **limit** и **offset**.

```php
// В контроллере
$total = $connection->table('users')->count();
$pagination = $this->paginationFactory->create($total, 5);

$users = $connection->table('users')
    ->limit($pagination->getPerPage())
    ->offset($pagination->getOffset())
    ->get();

return new ViewResponse('@partners/public/index.twig', [
    'users'      => $users,
    'pagination' => $pagination->render(),
]);
```

Метод `render()` возвращает готовую разметку навигации, а адреса страниц строятся из текущего URL — заботиться об их формировании не нужно. В шаблоне она выводится как обычная переменная:

```twig
{{ pagination }}
```

Шаблон постраничной навигации расположен тут:\
**themes/default/templates/components/pagination.twig**

### **Выборка только необходимых столбцов**

Иногда вам может понадобиться выбрать только определенные столбцы из таблицы в базе данных.\
Сделать это можно так:

```php
$user = $connection->table('users')->select(['name', 'id'])->get();
foreach ($user as $item) {
    echo $item->id . ' - ' . $item->name;
}
```

Для выборки конкретных столбцов используется метод select(). Он принимает названия столбцов в виде массива или просто списком аргументов. Например: **select('name', 'id')**

### **Сортировка результата выборки**

Часто есть необходимость отсортировать результат выборки по какому-либо столбцу.

```php
$user = $connection->table('users')
    ->select('name', 'id')
    ->orderBy('id')
    ->orderByDesc('name')
    ->get();
foreach ($user as $item) {
    echo $item->id . ' - ' . $item->name;
}
```

В этом примере результат будет отсортирован по **id** и **name**. Метод **orderBy** вторым аргументом принимает направление сортировки **asc** или **desc**. По умолчанию **asc**. Метод **orderByDesc** это то же самое, что и **orderBy('id', 'desc')**\
Как видно из примера, сортировать можно по нескольким колонкам. Указанный выше пример выполнит следующий запрос к базе данных:

```sql
select `name`, `id` from `users` order by `id` asc, `name` desc
```

Мы рассмотрели общий принцип построения запросов.\
Если вы хотите ознакомиться подробно с конструктором запросов, вы можете это сделать [здесь](https://laravel.com/docs/7.x/queries) или на русском: [здесь](https://laravel.su/docs/5.4/queries)\
Обратите внимание, что для выполнения запросов нужно использовать объект **$connection,** а не **DB::**. В остальном все возможности, которые описаны по ссылкам, будут работать и в JohnCMS.
