-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDatabase.php
More file actions
executable file
·120 lines (108 loc) · 4.19 KB
/
Copy pathDatabase.php
File metadata and controls
executable file
·120 lines (108 loc) · 4.19 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
<?php
namespace FpDbTest;
use Exception;
use mysqli;
class Database implements DatabaseInterface
{
private mysqli $mysqli;
public function __construct(mysqli $mysqli)
{
$this->mysqli = $mysqli;
}
/**
* @throws Exception
*/
public function buildQuery(string $query, array $args = []): string
{
$i = -1;
$query_string = preg_replace_callback(
'/(\?)[d|f|a|#|$]|(\?)/x',
function ($matches) use (&$i, $args) {
++$i;
$str = match ($matches[0]) {
'?#' => $this->checkNullAndSkip($args[$i]) ?? match (true) {
is_string($args[$i]) => "`{$args[$i]}`",
is_array($args[$i]) => implode(
", ",
array_map(fn($a) => "`{$a}`", $args[$i]),
),
default => throw new Exception(),
},
'?a' => $this->checkNullAndSkip($args[$i]) ?? match (true) {
is_array($args[$i]) => (function () use ($i, $args) {
if (array_is_list($args[$i])) {
return implode(", ", $args[$i]);
} else {
$arraySet = array_map(
function ($k, $v): string {
$b = $this->formatValue($v);
return "`$k` = " . (is_string($b)
? addslashes($b) : $b);
},
array_keys($args[$i]),
array_values($args[$i]),
);
return implode(", ", $arraySet);
}
})(),
default => throw new Exception('Ошибка спецификатора'),
},
'?d' => $this->checkNullAndSkip($args[$i]) ?? intval($args[$i]),
'?f' => $this->checkNullAndSkip($args[$i]) ?? floatval($args[$i]),
'?' => $this->checkNullAndSkip($args[$i]) ?? match (true) {
is_string($args[$i]) => addslashes("'{$args[$i]}'"),
default => $this->formatValue($args[$i])
},
default => throw new Exception('Неправильный идентификатор'),
};
return $str;
},
$query,
);
$regex_skip = "/[\{](.+)?({$this->skipValue()}){1}(.+)?[\}$]/";
return preg_replace([$regex_skip, '[{|}]'], [''], $query_string);
}
/**
* Специальное значение, размещенный внутри блока {специальное_значение}
* запроса означает, что данный блок должен быть удален с данного запроса
*
* @return string
*/
public function skipValue(): string
{
return 'skip_for_block';
}
/**
* Проверяем типы входящего параметра и
* форматируем в зависимости от типа
*
* @param mixed $value
*
* @return float|int|string|Exception
* @throws Exception
*/
private function formatValue(mixed $value): float|int|string|Exception
{
return match (true) {
is_bool($value) => true ? 1 : 0,
is_string($value) => "'$value'",
is_int($value), is_float($value) => $value,
is_null($value) => 'NULL',
default => throw new Exception('Ошибка типа'),
};
}
/**
* Проверка на null и специальное значение
* @param mixed $value
*
* @return mixed
*/
private function checkNullAndSkip(mixed $value): mixed
{
return match (true) {
is_null($value) => 'NULL',
$this->skipValue() === $value => $value,
default => null
};
}
}