Skip to content

Commit 379329d

Browse files
Реализация компонента
0 parents  commit 379329d

File tree

6 files changed

+416
-0
lines changed

6 files changed

+416
-0
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/vendor/

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2021 Maxim N Epikhin
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# php-database
2+
3+
Компонент для работы с базой данных в PHP. Данный компонент помогает подготавливать запросы, выполнять различные выборки
4+
и организовывать транзакции.
5+
6+
# Структура
7+
8+
```
9+
src/
10+
--- interfaces/
11+
--- Database.php
12+
```
13+
14+
В директории `interfaces` хранятся необходимые интерфейсы, которые необходимо имплементировать в при реализации
15+
собственного класса `Database`.
16+
17+
Класс `Database` реализует интерфейс `DatabaseInterface` для управления работы с базой данных.
18+
19+
# Доступные методы
20+
21+
| Метод | Аргументы | Возвращаемые данные | Исключения | Описание |
22+
|---------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------|---------------------|--------------|----------------------------------------------------------------------------|
23+
| connect(array $databaseConnectionParams = []) | Параметры соединения | void | | Создает подключение к базе данных |
24+
| closeConnection() | | void | | Закрывает подключение к базе данных |
25+
| beginTransaction() | | void | | Начинает транзакцию |
26+
| commit() | | void | | Выполняет транзакцию |
27+
| execute(string $query, array $attributes = []) | $query Запрос; $attributes Атрибуты | bool | PDOException | Выполняет запрос |
28+
| queryAll(string $query, array $attributes = [], $fetchStyle = PDO::FETCH_ASSOC) | $query Запрос; $attributes Атрибуты; $fetchStyle Определяет содержимое возвращаемого массива | array | PDOException | Возвращает массив, содержащий все строки результирующего набора |
29+
| queryRow(string $query, array $attributes = [], $fetchStyle = PDO::FETCH_ASSOC) | $query Запрос; $attributes Атрибуты; $fetchStyle Определяет содержимое возвращаемого массива | mixed | PDOException | Возвращает строку результирующего набора |
30+
| queryColumn(string $query, array $attributes = []) | $query Запрос; $attributes Атрибуты | array | PDOException | Возвращает колонку результирующего набора |
31+
| queryOne(string $query, array $attributes = []) | $query Запрос; $attributes Атрибуты | | PDOException | Возвращает единственную запись результирующего набора |
32+
| getLastInsertId() | | string | | Возвращает ID последней вставленной строки или значение последовательности |
33+
34+
# Контакты
35+
36+
Вы можете связаться со мной в социальной сети ВКонтакте: [ВКонтакте: Максим Епихин](https://vk.com/maximepihin)
37+
38+
Если удобно писать на почту, то можете воспользоваться этим адресом: mepihindeveloper@gmail.com
39+
40+
Мой канал на YouTube, который посвящен разработке веб и игровых
41+
проектов: [YouTube: Максим Епихин](https://www.youtube.com/channel/UCKusRcoHUy6T4sei-rVzCqQ)
42+
43+
Поддержать меня можно переводом на Яндекс.Деньги: [Денежный перевод](https://yoomoney.ru/to/410012382226565)

composer.json

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
{
2+
"name": "mepihindeveloper/php-database",
3+
"description": "Component for working with a database",
4+
"type": "library",
5+
"license": "MIT",
6+
"keywords": [
7+
"component",
8+
"class",
9+
"php",
10+
"database"
11+
],
12+
"authors": [
13+
{
14+
"name": "mepihindeveloper",
15+
"email": "mepihindeveloper@gmail.com"
16+
}
17+
],
18+
"require": {
19+
"php": ">=7.4"
20+
},
21+
"autoload": {
22+
"psr-4": {
23+
"mepihindeveloper\\components\\": "src/"
24+
}
25+
},
26+
"minimum-stability": "dev",
27+
"prefer-stable": true
28+
}

src/Database.php

Lines changed: 203 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,203 @@
1+
<?php
2+
3+
declare(strict_types = 1);
4+
5+
namespace mepihindeveloper\components;
6+
7+
use PDO;
8+
use PDOException;
9+
use PDOStatement;
10+
use RuntimeException;
11+
12+
/**
13+
* Класс Database
14+
* Класс реализует подключение и управление запросами к базе данных
15+
*
16+
* @package mepihindeveloper\components
17+
*/
18+
class Database implements interfaces\DatabaseInterface {
19+
20+
/**
21+
* @var PDOStatement[] Список подготовленных запросов
22+
*/
23+
public array $executeList = [];
24+
/**
25+
* @var bool Статус активности транзакции
26+
*/
27+
public bool $isTransaction = false;
28+
/**
29+
* @var PDO|null Соединение с базой данных
30+
*/
31+
protected ?PDO $pdo;
32+
/**
33+
* @var PDOStatement Подготовленный запрос
34+
*/
35+
protected PDOStatement $pdoStatement;
36+
37+
/**
38+
* @inheritDoc
39+
*/
40+
public function connect(array $databaseConnectionParams = []): void {
41+
$dsn = "{$databaseConnectionParams['dbms']}:";
42+
43+
foreach (['host', 'dbname'] as $key) {
44+
$dsn .= "{$key}={$databaseConnectionParams[$key]};";
45+
}
46+
47+
$charset = array_key_exists('charset', $databaseConnectionParams) ? strtoupper($databaseConnectionParams['charset']) : 'UTF8';
48+
$this->pdo = new PDO(
49+
$dsn,
50+
$databaseConnectionParams['user'],
51+
$databaseConnectionParams['password']
52+
);
53+
$this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
54+
$this->pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, true);
55+
$this->pdo->exec("SET NAMES '{$charset}'");
56+
}
57+
58+
/**
59+
* @inheritDoc
60+
*/
61+
public function closeConnection(): void {
62+
$this->pdo = null;
63+
}
64+
65+
/**
66+
* @inheritDoc
67+
*/
68+
public function beginTransaction(): void {
69+
if ($this->isTransaction) {
70+
throw new RuntimeException('Ошибка. Невозможно повторно инициализировать транзакцию.');
71+
}
72+
73+
$this->pdo->beginTransaction();
74+
$this->isTransaction = true;
75+
}
76+
77+
/**
78+
* @inheritDoc
79+
*/
80+
public function commit(): void {
81+
try {
82+
if (!empty($this->executeList)) {
83+
foreach ($this->executeList as $executeQuery) {
84+
$executeQuery->execute();
85+
}
86+
}
87+
88+
$this->pdo->commit();
89+
} catch (PDOException $exception) {
90+
$this->pdo->rollBack();
91+
92+
throw new PDOException(500, $exception->getMessage(), $exception->getCode());
93+
} finally {
94+
$this->isTransaction = false;
95+
$this->executeList = [];
96+
}
97+
}
98+
99+
/**
100+
* @inheritDoc
101+
*/
102+
public function queryAll(string $query, array $attributes = [], $fetchStyle = PDO::FETCH_ASSOC): array {
103+
$this->execute($query, $attributes);
104+
105+
return $this->pdoStatement->fetchAll($fetchStyle);
106+
}
107+
108+
/**
109+
* @inheritDoc
110+
*/
111+
public function execute(string $query, array $attributes = []): bool {
112+
$this->beforeQuery($query, $attributes);
113+
114+
return $this->pdoStatement->execute();
115+
}
116+
117+
/**
118+
* Обрабатывает запрос перед выполнением
119+
*
120+
* @param string $query Запрос
121+
* @param array $attributes Атрибуты запроса
122+
*
123+
* @return void
124+
* @throws PDOException
125+
*/
126+
protected function beforeQuery(string $query, array $attributes = []): void {
127+
try {
128+
$this->pdoStatement = $this->pdo->prepare($query);
129+
130+
if (!empty($attributes)) {
131+
$preparedAttributes = $this->bindAttributes($attributes);
132+
133+
foreach ($preparedAttributes as $preparedAttribute) {
134+
$attributesPart = explode("\x7F", $preparedAttribute);
135+
$this->pdoStatement->bindParam($attributesPart[0], $attributesPart[1]);
136+
}
137+
}
138+
139+
if ($this->isTransaction) {
140+
$this->executeList[] = $this->pdoStatement;
141+
}
142+
} catch (PDOException $exception) {
143+
throw new PDOException(500, $exception->getMessage(), $exception->getCode());
144+
}
145+
}
146+
147+
/**
148+
* Назначает атрибуты
149+
*
150+
* @param array $attributes Атрибуты
151+
*
152+
* @return array
153+
*/
154+
protected function bindAttributes(array $attributes): array {
155+
$preparedAttributes = [];
156+
157+
foreach ($attributes as $key => $value) {
158+
$preparedAttributes[] = ':' . $key . "\x7F" . $value;
159+
}
160+
161+
return $preparedAttributes;
162+
}
163+
164+
/**
165+
* @inheritDoc
166+
*/
167+
public function queryRow(string $query, array $attributes = [], $fetchStyle = PDO::FETCH_ASSOC) {
168+
$this->execute($query, $attributes);
169+
170+
return $this->pdoStatement->fetch($fetchStyle);
171+
}
172+
173+
/**
174+
* @inheritDoc
175+
*/
176+
public function queryColumn(string $query, array $attributes = []): array {
177+
$this->execute($query, $attributes);
178+
$queryCells = $this->pdoStatement->fetchAll(PDO::FETCH_NUM);
179+
$cells = [];
180+
181+
foreach ($queryCells as $queryCell) {
182+
$cells[] = $queryCell[0];
183+
}
184+
185+
return $cells;
186+
}
187+
188+
/**
189+
* @inheritDoc
190+
*/
191+
public function queryOne(string $query, array $attributes = []) {
192+
$this->execute($query, $attributes);
193+
194+
return $this->pdoStatement->fetchColumn();
195+
}
196+
197+
/**
198+
* @inheritDoc
199+
*/
200+
public function getLastInsertId(): string {
201+
return $this->pdo->lastInsertId();
202+
}
203+
}

0 commit comments

Comments
 (0)