Singleton в PHP на примере подключения к MySQL
Singleton (синглтон, одиночка) – один из простейших для понимания шаблонов проектирования в PHP. Это обычный класс в PHP, в логику которого добавлена проверка на единственность создания его экземпляра.
Назначение одиночки
Согласно определению, одиночка — один из самых простых паттернов, когда происходит проверка того, что экземпляр всего один и к нему обеспечивается единая точка доступа. Многие специалисты и вовсе считают его антипаттерном.
Назначение Singleton — сделать объект единственным экземпляром класса. Позволяет получить доступ к уникальному объекту из любой точки приложения.
Как создать Singleton:
- хранить экземпляр класса в приватной статической переменной;
- инициализировать его через метод getInstance и сохранять в статической переменной, а если она была создана раньше, то вернуть ее;
- определить метод __construct в private и определить в нем логику создания instance;
- определить метод __clone (клонирование объекта) как private;
- определить метод __wakeup (вызывается перед unserialize) как private.
Почему стоит использовать Singleton:
- позволяет иметь общую точку доступа к внешнему ресурсу;
- упрощает инициализацию, проверку состояния, передачу контекста в приложении;
- при грамотном использовании (примеры ниже), упрощает управление приложением.
Когда стоит использовать Singleton:
- подключение к БД;
- класс, инициализирующий настройки приложения, состояние, контекст.
Почему не стоит использовать Singleton
- нарушает принцип единственной ответственности (проверяет на существование, создает экземпляр, отдает результат);
- затрудняет тестирование, т.е. приносит в приложение глобальное состояние;
- скрытые зависимости.
Пример
Рассмотрим использование одиночки на примере создания соединения к базе данных MySQL.
Создадим класс DB. Информацию о соединении будем хранить в статической приватной переменной $_instance. Чтобы получить ее значение будем использовать статический метод getInstance(), в котором будем делать проверку на null переменной $_instance, в случае истины создавать ее через new self, иначе – возвращать ее.
Пример реализации этого класса:
'mysql:host=' . self::DB_HOST . ';dbname=' . self::DB_NAME,
self::DB_USER,
self::DB_PASS,
[PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'utf8'"]
);
}
private function __clone () {}
private function __wakeup () {}
public static function getInstance()
{
if (self::$_instance != null) {
return self::$_instance;
}
return new self;
}
}
Использование
$db = DB::getInstance(); $db2 = DB::getInstance(); var_dump($db == $db2); // bool(true)


Сообщить об опечатке
Текст, который будет отправлен нашим редакторам: