Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions design_patterns/abstract_factory/.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
DB_DRIVER=pgsql
DB_HOST=db
DB_PORT=5432
DB_DATABASE=movie
DB_USERNAME=root
DB_PASSWORD=password
15 changes: 15 additions & 0 deletions design_patterns/abstract_factory/Container.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php

declare(strict_types=1);

class Container
{
public static function make(string $driver): DbFactoryInterface
{
return match ($driver) {
'mysql' => new MySqlFactory(),
'pgsql' => new PgSqlFactory(),
default => throw new RuntimeException('Неизвестный драйвер базы данных'),
};
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?php

declare (strict_types = 1);

interface DbConnectionInterface
{
public function connect(array $config): void;

public function execute(string $sql, array $bindings = []): array;

public function getPdo(): PDO;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php

declare (strict_types = 1);
interface DbFactoryInterface
{
public function connection(): DbConnectionInterface;
public function queryBuilder(): QueryBuilderInterface;
public function transaction(): TransactionInterface;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

declare (strict_types = 1);

interface QueryBuilderInterface
{
public function select(string $table): self;

public function limit(int $limit): self;

public function get(): string;

public function paginate(int $limit, int $offset): self;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php

declare (strict_types = 1);
interface TransactionInterface
{
public function start(): void;
public function commit(): void;
public function rollback(): void;
}
36 changes: 36 additions & 0 deletions design_patterns/abstract_factory/MySQL/MySQLConnection.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?php

declare (strict_types = 1);

class MySQLConnection implements DbConnectionInterface
{
private ?PDO $pdo = null;

public function connect(array $config): void
{
if ($this->pdo !== null) {
return;
}

$dsn = "mysql:host={$config['host']};dbname={$config['db']};charset={$config['charset']}";
$this->pdo = new PDO($dsn, $config['user'], $config['password'], [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
]);
}

public function execute(string $sql, array $bindings = []): array
{
if ($this->pdo === null) {
throw new RuntimeException('Ошибка подключения к базе данных');
}
$stmt = $this->pdo->prepare($sql);
$stmt->execute($bindings);
return $stmt->fetchAll();
}

public function getPdo(): PDO
{
return $this->pdo;
}
}
39 changes: 39 additions & 0 deletions design_patterns/abstract_factory/MySQL/MySQLQueryBuilder.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?php

declare (strict_types = 1);
class MySQLQueryBuilder implements QueryBuilderInterface
{
private string $table = '';
private string $limit = '';

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

return $this;
}

public function limit(int $limit): self
{
$this->limit = "LIMIT {$limit}";

return $this;
}

public function paginate(int $limit, int $offset): self
{
$this->limit = "LIMIT {$offset}, {$limit}";

return $this;
}

public function get(): string
{
$sql = "SELECT * FROM {$this->table} {$this->limit}";

$this->table = '';
$this->limit = '';

return $sql;
}
}
22 changes: 22 additions & 0 deletions design_patterns/abstract_factory/MySQL/MySQLTransaction.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php

declare (strict_types = 1);

class MySQLTransaction implements TransactionInterface
{
public function __construct(private DbConnectionInterface $connection)
{}

public function start(): void
{
$this->connection->getPdo()->beginTransaction();
}
public function commit(): void
{
$this->connection->getPdo()->commit();
}
public function rollback(): void
{
$this->connection->getPdo()->rollBack();
}
}
25 changes: 25 additions & 0 deletions design_patterns/abstract_factory/MySQL/MySqlFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

declare (strict_types = 1);

class MySqlFactory implements DbFactoryInterface
{
private ?DbConnectionInterface $connection = null;

public function connection(): DbConnectionInterface
{
if ($this->connection === null) {
$this->connection = new MySQLConnection();
}
return $this->connection;
}
public function queryBuilder(): QueryBuilderInterface
{
return new MySQLQueryBuilder();
}

public function transaction(): TransactionInterface
{
return new MySQLTransaction($this->connection());
}
}
38 changes: 38 additions & 0 deletions design_patterns/abstract_factory/PgSQL/PgSQLConnection.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?php

declare (strict_types = 1);

class PgSQLConnection implements DbConnectionInterface
{
private ?PDO $pdo = null;

public function connect(array $config): void
{
if ($this->pdo !== null) {
return;
}

$dsn = "pgsql:host={$config['host']};dbname={$config['db']};charset={$config['charset']}";
$this->pdo = new PDO($dsn, $config['user'], $config['password'],
[
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
]);
}

public function execute(string $sql, array $bindings = []): array
{
if ($this->pdo === null) {
throw new RuntimeException('Ошибка подключения к базе данных');
}

$stmt = $this->pdo->prepare($sql);
$stmt->execute($bindings);
return $stmt->fetchAll();
}

public function getPdo(): PDO
{
return $this->pdo;
}
}
40 changes: 40 additions & 0 deletions design_patterns/abstract_factory/PgSQL/PgSQLQueryBuilder.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?php

declare (strict_types = 1);

class PgSQLQueryBuilder implements QueryBuilderInterface
{
private string $table = '';
private string $limit = '';

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

return $this;
}

public function limit(int $limit): self
{
$this->limit = "LIMIT {$limit}";

return $this;
}

public function paginate(int $limit, int $offset): self
{
$this->limit = "LIMIT {$limit} OFFSET {$offset}";

return $this;
}

public function get(): string
{
$sql = "SELECT * FROM {$this->table} {$this->limit}";

$this->table = '';
$this->limit = '';

return $sql;
}
}
22 changes: 22 additions & 0 deletions design_patterns/abstract_factory/PgSQL/PgSQLTransaction.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php

declare (strict_types = 1);

class PgSQLTransaction implements TransactionInterface
{
public function __construct(private DbConnectionInterface $connection)
{}

public function start(): void
{
$this->connection->getPdo()->beginTransaction();
}
public function commit(): void
{
$this->connection->getPdo()->commit();
}
public function rollback(): void
{
$this->connection->getPdo()->rollBack();
}
}
25 changes: 25 additions & 0 deletions design_patterns/abstract_factory/PgSQL/PgSqlFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

declare (strict_types = 1);

class PgSqlFactory implements DbFactoryInterface
{
private ?DbConnectionInterface $connection = null;

public function connection(): DbConnectionInterface
{
if ($this->connection === null) {
$this->connection = new PgSQLConnection();
}
return $this->connection;
}
public function queryBuilder(): QueryBuilderInterface
{
return new PgSQLQueryBuilder();
}

public function transaction(): TransactionInterface
{
return new PgSQLTransaction($this->connection);
}
}
37 changes: 37 additions & 0 deletions design_patterns/abstract_factory/index.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php

declare(strict_types=1);

$config = [
'driver' => env('DB_DRIVER', 'pgsql'),
'host' => env('DB_HOST', 'localhost'),
'db' => env('DB_DATABASE', 'localhost'),
'port' => env('DB_PORT'),
'user' => env('DB_USERNAME'),
'password' => env('DB_PASSWORD'),
'charset' => env('utf8mb4')
];

$factory = Container::make($config['driver']);

$connection = $factory->connection();
$connection->connect($config);

//Пример запроса
$sql = $factory->queryBuilder()
->select('movie')
->paginate(10, 20)
->get();


$movie = $connection->execute($sql);

// Пример транзакции
$transaction = $factory->transaction();
$transaction->start();
try {
// Что-то реализуем
$transaction->commit();
} catch (\Exception $e) {
$transaction->rollback();
}
11 changes: 11 additions & 0 deletions design_patterns/observer/BonusListener.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php

declare (strict_types = 1);

class BonusListener implements ListenerInterface
{
public function handle(object $event): void
{
echo "Пользователю {$event->userId} начислено 100 бонусов.";
}
}
11 changes: 11 additions & 0 deletions design_patterns/observer/EmailListener.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php

declare (strict_types = 1);

class EmailListener implements ListenerInterface
{
public function handle(object $event): void
{
echo "Отправлено приветственное письмо на {$event->email}";
}
}
Loading