Muranx
@Muranx
кто понял this тот в цирке не смеётся

Как сформировать запрос к базе данных?

Здравствуйте!

Со фронтэнда приходит запрос на сервер, содержащий в себе массив для фильтрации запросов :

[         
     {property: 'name', value: 'al'},
     {property: 'surename', value: 'br'}
     {property: 'order_by', value: 'name'}  
];


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

SELECT * FROM `users` WHERE `users`.`name` LIKE 'al%' AND `users`.`surename` LIKE 'br%' LIMIT 0,5 ORDER BY 'name'


За не имением опыта, единственное что приходит в голову, создать какой-нибудь класс парсер, который на стороне сервера будет парсить этот объект (с фронта), и превращать его (наверное очень сложным образом) в строку запроса sql, какие Вы можете подсказать варианты, т.к. что-то мне подсказывает что это можно сделать проще? Офк в этом объекте сортировки может вообще не быть свойств а может быть их и больше, их порядок не гарантирован, а так-же если сейчас все сортировки подходят под LIKE '...' то в будущем возможно понадобится выбирать значения которые например больше или меньше другого...
  • Вопрос задан
  • 177 просмотров
Решения вопроса 1
Compolomus
@Compolomus Куратор тега PHP
Комполом-быдлокодер
Вам надо две вещи, первое это инструмент для разбора данных с фронта, хотя бы превращение в обычный массив, второе это какой нибудь query builder
Первое решается элементарно, это обычный массив объектов, второе можно поискать на гитхаб
пишем простой свой билдер на примере запроса
допилить напильником
<?php

$builder = new Builder();
$query = $builder
        ->table('test')
        ->select(['*'])
        ->where(['field1', 'in', [1,2,3]], ['field2', 'like', '%ab%'])
        ->limit(10, 20)
        ->get();
$placeholders = $builder->getPlaceholders();

$result = $pdo->prepare($query)->execute($placeholders);
/* фетч результата */


<?php

namespace Compolomus\Builder;

use RuntimeException;

final class Builder
{
    private ?string $table = null;

    private array $where = [];

    private array $columns = ['*'];

    private array $placeholders = [];

    private ?string $queryType = null;

    public function __construct(?string $table = null)
    {
        if (!is_null($table)) {
            $this->table = $table;
        }
    }

    public function table(string $table): Builder
    {
        $this->table = $table;

        return $this;
    }

    public function count(): Builder
    {
        $this->queryType = 'select count(*)';

        return $this;
    }

    public function select(?array $columns = null): Builder
    {
        if (!is_null($columns)) {
            $this->columns = $columns;
        }

        return $this;
    }

    public function limit(int $limit, int $offset = 0): Builder
    {
        /*
         тут собираем строку с лимит и куда нибудь сохраняем
         */
        return $this;
    }

    public function where(array $conditions, string $type = 'and'): Builder
    {
        foreach ($conditions as [$field, $condition, $value]) {
            /* тут собираем строку из поля, значения и типа */
            /* вместо значения подставляем плейсхолдер ? для подготовленных выражений */
            $this->placeholders[] = $value;
        }

        /* куда то сохраняем собранную строку,
         по типу собираем массив с типом обьединения,
         тут на самом деле всё сложно,
         возможно проще будет создать Where класс и отдать туда обработку
        */

        return $this;
    }

    /**
     * @throws RuntimeException
     */
    public function get(): string
    {
        if (is_null($this->queryType)) {
            throw new RuntimeException('Undefined query type');
        }

        $query = strtoupper($this->queryType);
        /* тут собираем весь запрос из кусочков */

        return $query;
    }

    public function getPlaceholders(): array
    {
        $placeholders = $this->placeholders;

        $this->placeholders = [];
        /* обязательно обнуляем, возможно и весь билдер для следующего запроса */

        return $placeholders;
    }

}
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы