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)
Сообщить об опечатке
Текст, который будет отправлен нашим редакторам: