@Andy91

PHP. Singletone для pdo. Как реализовать?

Добрый день! только начинаю изучать php и ещё слаб в шаблонах проектирования, в сети наткнулся на кучу разных вариантов, но они какие-то все странные....
И встают вопросы:
1) Нужно ли вообще использовать этот шаблон для БД? И чем страшно создание множества объектов PDO?
2) Как я понял при наследовании дочерним классом класса PDO, нельзя переопределить идентификатор доступа на protected для __construct?

Написал вот такой класс для реализации singletone:
class DB  {

    static $db;
    static $instance;

    protected function __construct($dsn,$username,$password,$options) {
        self::$instance = new PDO($dsn,$username,$password,$options);
    }
    
    public static function getInstance($dsn,$username,$password,$options) {
        if(self::$instance instanceof PDO){
            return self::$instance;
        } else {
            if(self::$db instanceof self){
                exit('Ошибка работы БД!') ;
            } else {
                self::$db = new self($dsn, $username, $password, $options);
                return self::$instance;
            }
        }
    }
}


Вроде отрабатывает корректно, но был бы рад конструктивной критики в его адрес с пояснениями!)))
  • Вопрос задан
  • 2855 просмотров
Решения вопроса 1
FanatPHP
@FanatPHP
Чебуратор тега РНР
Ответ на этот вопрос очень простой.

- Если ты пишешь процедурный код, то в синглтоне нет никакого вреда, а только одна польза.
- Если же ты пишешь объектный код, то синглтон тебе просто не нужен, поскольку в объект при создании всегда можно передать инстанс класса для работы с БД и присвоить переменной класса.

по поводу реализации

1. Как уже сказали выше, какой-то странный метод getInstance(). Если каждый раз вызывать с парасетрами, то какой вообще смысл в синглтоне? Сделай хотя бы два метода, один коннект, а второй гетинстанс.
2. Не очень понятно почему две статические переменные, и какая за что отвечает. почему бы не оставить одну?
3. Если уж делать синглтон, то лучше избавляться от лишней писанины, и обращаться напрямую к методам для работы с БД: `DB::insertId()` будет поудобнее, чем `DB::getInstance()->insertId()`
4. Учитывая неудобство метода PDO::execute(), будет полезным подправить классиков и добавить метод, который будет выполнять запрос с параметрами и вернет стейтмент. Пример можно посмотреть здесь: https://phpdelusions.net/pdo/pdo_wrapper
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 3
@McBernar
В следующий раз, когда вам скажут, что синглтон — это антипаттерн или он "маскирует зависимости" — попросите этого человека показать реальный пример, когда синглтон маскирует зависимости.
Ответ написан
@synapse_people
Какой смысл от такого статического метода, если он принимает все параметры конструктора?
Перенесите создание PDO объекта в публичный метод. Чтобы получилось примерно так:
$db = DB::getInstance();
$db->connect(host,port,db.....);
Еще лучше, если DB будет наследовать(extends) PDO.
затем сделайте интерфейс DbAware с методом setDb - для всех остальных классов, которые будут использовать базу данных. И засуньте это все в какой-то контейнер зависимостей.
Ответ написан
Комментировать
@heahoh
Full stackoverflow developer
Посмотрите тут
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы