Реализация паттерна проектирования Singleton (Одиночка) на PHP
7 ноября 2024 г.
55
В объектно-ориентированном программировании (ООП) паттерн Singleton (Одиночка) — это паттерн проектирования программного обеспечения, который ограничивает создание экземпляра класса единственным экземпляром. Паттерн полезен, когда для координации действий в системе требуется ровно один объект.
Паттерн Singleton (Одиночка):
- гарантирует, что у них есть только один экземпляр;
- предоставляет легкий доступ к этому экземпляру;
- управляет созданием экземпляров (например, скрывая конструкторы класса).
Код класса для паттерна Singleton (Одиночка):
class Database
{
protected static self|null $instance = null;
private $_db;
final private function __construct()
{
try {
$this->_db = new \PDO("mysql:host=<host>:<port>;dbname=<dbname>", "<user>", "<password>", array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8"));
} catch (PDOException $e) {
die($e->getMessage());
}
}
final protected function __clone(){}
final public function __wakeup(){}
public function query_select (string $sql, array $params = []): ?array
{
$sth = $this->_db->prepare($sql);
$result = $sth->execute($params);
if (false === $result) {
return null;
}
return $sth->fetchAll(\PDO::FETCH_CLASS);
}
public function query_insert (string $sql, array $params = [])
{
$sth = $this->_db->prepare($sql);
$result = $sth->execute($params);
if (false === $result) {
return null;
}
}
public function disconnect()
{
$this->_db = null;
}
public static function getInstance(): static
{
if (static::$instance === null) {
static::$instance = new static;
}
return static::$instance;
}
}
Проверяем как работает данный код. Создаём три объекта класса Database:
$db1 = Database::getInstance();
var_dump($db1);
$db2 = Database::getInstance();
var_dump($db2);
$db3 = Database::getInstance();
$db3->disconnect();
var_dump($db3);
Смотрим что выводится в dump:
object(Database)#1 (1) { ["_db":"Database":private]=> object(PDO)#2 (0) { } } // db1
object(Database)#1 (1) { ["_db":"Database":private]=> object(PDO)#2 (0) { } } // db2
object(Database)#1 (1) { ["_db":"Database":private]=> NULL } // db3
Во всех трёх случаях мы работаем с одним и тем же объектом
object(Database)#1. Паттерн реализован и работает.