2024-05-14 14:24:54 +00:00
|
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
namespace Helper;
|
|
|
|
|
|
|
|
|
|
use Exception;
|
|
|
|
|
|
|
|
|
|
class QueryBuilder
|
|
|
|
|
{
|
|
|
|
|
public function __construct(private readonly string $tableName, private string $columns = '*') {}
|
|
|
|
|
|
|
|
|
|
public function setColumns(string $columns): void
|
|
|
|
|
{
|
|
|
|
|
$this->columns = $columns;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @throws Exception
|
|
|
|
|
*/
|
|
|
|
|
public function select(array $filters = [], int $limit = 0): array
|
|
|
|
|
{
|
|
|
|
|
if (empty($filters)) {
|
2024-05-15 13:42:28 +00:00
|
|
|
|
return ['sql' => "select $this->columns from $this->tableName"];
|
2024-05-14 14:24:54 +00:00
|
|
|
|
}
|
|
|
|
|
$where = [];
|
|
|
|
|
$params = [];
|
|
|
|
|
foreach ($filters as $filter) {
|
|
|
|
|
[$name, $operation, $value] = explode(' ', $filter, 3);
|
|
|
|
|
$placeholder = ":$name";
|
2024-05-15 13:42:28 +00:00
|
|
|
|
$value = explode(' ', $value, 3); //todo: а ведь может прилететь значение из нескольких слов с пробелом...
|
2024-05-14 14:24:54 +00:00
|
|
|
|
if (count($value) === 1) {
|
|
|
|
|
$value = $value[0];
|
|
|
|
|
if (is_numeric($value)) {
|
|
|
|
|
$value = (int)$value;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
array_walk_recursive($value, function (&$var) {
|
|
|
|
|
if (is_numeric($var)) {
|
|
|
|
|
$var = (int)$var;
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
if (is_numeric($value[0]) && is_numeric($value[2])) {
|
|
|
|
|
$value = match ($value[1]) {
|
|
|
|
|
'+' => $value[0] + $value[2],
|
|
|
|
|
'-' => $value[0] - $value[2],
|
|
|
|
|
'*' => $value[0] * $value[2],
|
|
|
|
|
'/' => ($value[2] != 0) ? $value[0] / $value[2] : throw new Exception('Деление на ноль недопустимо.'),
|
|
|
|
|
default => throw new Exception('Недопустимый оператор. Допустимы: +, -, *, /.'),
|
|
|
|
|
};
|
|
|
|
|
} elseif (is_string($value[0])) {
|
|
|
|
|
$placeholder = "$value[0] $value[1] :$name";
|
|
|
|
|
$value = $value[2];
|
|
|
|
|
} elseif (is_string($value[2])) {
|
|
|
|
|
$placeholder = "$value[2] $value[1] :$name";
|
|
|
|
|
$value = $value[0];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
//todo: но есть ещё форменное скотство, когда в запрос кидают сложные формулы...
|
|
|
|
|
|
|
|
|
|
$where[] = "$name $operation $placeholder";
|
|
|
|
|
$params[$name] = $value;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return [
|
|
|
|
|
'sql' => "select $this->columns from $this->tableName where " . implode(" and ", $where) . ($limit > 0 ? " limit $limit" : ""),
|
|
|
|
|
'binds' => $params,
|
|
|
|
|
];
|
|
|
|
|
}
|
|
|
|
|
}
|