За последние 24 часа нас посетили 18539 программистов и 1702 робота. Сейчас ищут 885 программистов ...

Singleton PHP

Тема в разделе "PHP для новичков", создана пользователем Oleksii, 13 апр 2016.

  1. Oleksii

    Oleksii Новичок

    С нами с:
    12 апр 2016
    Сообщения:
    22
    Симпатии:
    0
    PHP:
    1. class DB
    2. {
    3.     private static $_db;
    4.  
    5.     public static function getDB()
    6.     {
    7.         if(is_null(self::$_db)) self::$_db = new DB;
    8.         return self::$_db;
    9.     }
    10.     private function __construct()
    11.     {
    12.         $connect = new mysqli('localhost', 'root', '', 'mysite');
    13.         if(!$connect) die("ERROR!");
    14.     }
    15.     public function query($sql)
    16.     {
    17.         self::$_db->query($sql);
    18.     }
    19.     private function __clone() {}
    20.  
    21. }
    22. $obj = DB::getDB();
    23. $obj->query("CREATE TABLE IF NOT EXISTS table3('name text, surname text')");
    Fatal error: Maximum function nesting level of '256' reached, aborting! in C:\wamp64\www\mysite\db.php on line 16
    Что за ошибка и как исправить, уже по разному пробовал. К базе подключается а метод не работает.
     
    #1 Oleksii, 13 апр 2016
    Последнее редактирование модератором: 14 апр 2016
  2. MiksIr

    MiksIr Активный пользователь

    С нами с:
    29 ноя 2006
    Сообщения:
    2.339
    Симпатии:
    44
    query вызывает query, который вызывает query......
     
  3. Oleksii

    Oleksii Новичок

    С нами с:
    12 апр 2016
    Сообщения:
    22
    Симпатии:
    0
    DB::getDB()->query($query);
    без создания метола тоже ошибку выдает
     
  4. MiksIr

    MiksIr Активный пользователь

    С нами с:
    29 ноя 2006
    Сообщения:
    2.339
    Симпатии:
    44
    Потому что query вызывает query, который вызывает query......
     
  5. Oleksii

    Oleksii Новичок

    С нами с:
    12 апр 2016
    Сообщения:
    22
    Симпатии:
    0
    То есть название метода должно отличаться?
    Изменил
    Fatal error: Call to undefined method DB::query() in
     
  6. MiksIr

    MiksIr Активный пользователь

    С нами с:
    29 ноя 2006
    Сообщения:
    2.339
    Симпатии:
    44
    query нужно вызывать у инстанса mysqli, а не себя же
     
  7. Oleksii

    Oleksii Новичок

    С нами с:
    12 апр 2016
    Сообщения:
    22
    Симпатии:
    0
    так а self::$_db->query();
    это разве не вызов у инстанса?
     
  8. MiksIr

    MiksIr Активный пользователь

    С нами с:
    29 ноя 2006
    Сообщения:
    2.339
    Симпатии:
    44
    Вот вы себя и спросите - у инстанса какого класса вы делаете вызов.
     
  9. Oleksii

    Oleksii Новичок

    С нами с:
    12 апр 2016
    Сообщения:
    22
    Симпатии:
    0
    PHP:
    1. class DB
    2. {
    3.     private static $_db = null;
    4.     private $connect;
    5.  
    6.         private function __construct()
    7.     {
    8.         $this->connect = new mysqli('localhost', 'root', '', 'mysite');
    9.         if(!$this->connect) die("ERROR!");
    10.     }
    11.  
    12.     public static function getDB()
    13.     {
    14.         if(is_null(self::$_db))
    15.         {
    16.             $object = new DB;
    17.             self::$_db = $object->connect;
    18.         }
    19.         return self::$_db;
    20.     }
    21.  
    22.     public function query($sql)
    23.     {
    24.         self::$_db->query($sql);
    25.     }
    26.     private function __clone() {}
    27.  
    28. }
    29. $obj = DB::getDB();
    30. $obj->query("CREATE TABLE IF NOT EXISTS table3('name text, surname text')");
    вот так переписал, теперь ошибки нету, но и не выполняется запрос
     
  10. MiksIr

    MiksIr Активный пользователь

    С нами с:
    29 ноя 2006
    Сообщения:
    2.339
    Симпатии:
    44
    У вас ошибка в запросе.
    И зачем вам в таком виде класса new DB вообще? Или оставляйте new DB и
    возвращайте его инстанс, а в query уже к connect обращайтесь. Или вообще выкидывайте new DB, конструкторы, query и делайте new mysqli
     
  11. Oleksii

    Oleksii Новичок

    С нами с:
    12 апр 2016
    Сообщения:
    22
    Симпатии:
    0
    Какая ошибка в запросе? Вне класса работает этот запрос
    Выкинуть? Имеете ввиду без класса? Но я хочу с синглтоном разобраться
     
  12. mkramer

    mkramer Суперстар
    Команда форума Модератор

    С нами с:
    20 июн 2012
    Сообщения:
    8.600
    Симпатии:
    1.764
    Синглтон базы данных нужен для добавления хоть какого-то функционала, в вашем последнем случае он ничего не добавляет. Как избежать ошибки в изначальном коде, вам много раз подсказали
    PHP:
    1. class DB
    2. {
    3.    private static $_db;
    4.    private $connetct;
    5.    public static function getDB()
    6.    {
    7.        if(is_null(self::$_db))self::$_db=new DB;
    8.        returnself::$_db;
    9.    }
    10.    privatefunction __construct()
    11.    {
    12.        $this->connect=new mysqli('localhost','root','','mysite');
    13.        if(!$this->connect)die("ERROR!");
    14.    }
    15.    publicfunction query($sql)
    16.    {
    17.        return $this->connect->query($sql);
    18.    }
    19.    privatefunction __clone(){}
    20.  
    21. }
    Но в таком виде этот синглтон бесполезен, если вам не нужно добавлять никакого функционала, то используйте прямо mysqli.
     
  13. MiksIr

    MiksIr Активный пользователь

    С нами с:
    29 ноя 2006
    Сообщения:
    2.339
    Симпатии:
    44
    Лишние кавычки.
     
  14. Oleksii

    Oleksii Новичок

    С нами с:
    12 апр 2016
    Сообщения:
    22
    Симпатии:
    0
    Ну функционал я буду добавлять, просто смысл мне было сразу много добавлять если даже один запрос не работает. Спасибо, теперь работает.
     
  15. Kutuz

    Kutuz Новичок

    С нами с:
    10 апр 2016
    Сообщения:
    15
    Симпатии:
    0
    Синглетон в реалиях в основном применим в фасадных слоях приложения, используется в основном для "опорных точек" приложения,а эту часть я бы реализовал по крайней мере на статическом внедрении зависимостей, это обеспечит возможность расширения функционала в этой части, позволит тебе потом подменять объекты, если способы работы с БД изменятся, интерфейс останется, поэтому можно подумать о обобщенном интерфейсе для таких случаев
    Код (Text):
    1.  
    2. class DB
    3. {
    4.    protected static $_default;
    5.    protected $_connection;
    6.    public static function getDefault(){
    7.        if(is_null(self::$_db))self::$_db=new DB(['localhost','root','','mydb']);
    8.        returnself::$_db;
    9.    }
    10.    public static function setDefault(DB $db){
    11.        self::$_default = $db;
    12.    }
    13.    public function __construct($options){
    14.        $this->_connection = new mysqli($options[0],$options[1],$options[2],$options[3]);
    15.        if(!$this->_connection)die("ERROR!");
    16.    }
    17.    public function query($sql) {
    18.        return $this->_connection->query($sql);
    19.    }
    20.    // bonus
    21.    public static function __callStatic($m,$a){
    22.        return call_user_func_array([self::getDefault(),$m],$a);
    23.    }
    24.    private function __clone(){}
    25.  
    26. }
     
  16. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    космонавт детектед.
     
  17. Kutuz

    Kutuz Новичок

    С нами с:
    10 апр 2016
    Сообщения:
    15
    Симпатии:
    0
    ну тогда с прошедшим)
     
  18. MiksIr

    MiksIr Активный пользователь

    С нами с:
    29 ноя 2006
    Сообщения:
    2.339
    Симпатии:
    44
    Не обращай внимания, это местный постонабиватель.
     
  19. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    я прост не считаю правильным заранее закладывать механизмы, которые могут не понадобиться вообще никогда.
     
  20. mahmuzar

    mahmuzar Старожил

    С нами с:
    6 апр 2012
    Сообщения:
    4.631
    Симпатии:
    425
    Адрес:
    РД, г. Махачкала.
    А вдруг понадобятся? Переделывать потом всю систему, искать зависимости?
     
  21. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    Эмм. Да. Всю систему одного файла кверек в БД. Да. Да. Переделывать. Потом. Может быть. Возможно. Может и нет. Да, придётся отрефакторить четыре метода в одном файле.

    В противном случае можно всё заранее адаптировать под любые другие универсальности, которые в потенциале могут быть. А это пипец. В то время, как рефакторинг одного простого файла класса, который должен быть написан простым языком, без врзырвного кода - это быстро и просто. А если вы пишете сложно, если у вас длинные методы, не разбитые на подфункции - вы уже что-то делаете не так. Уже. И это уже надо исправлять до того, как вы вообще будете или не будете закладывать универсальность в ваш класс.
     
  22. Kutuz

    Kutuz Новичок

    С нами с:
    10 апр 2016
    Сообщения:
    15
    Симпатии:
    0
    Странно как тогда фреймворки живут и имеют свой кровный профит?.
     
  23. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    Во фреймворках это уже понадобилось. А у тебя ещё не популярный фреймворк, и даже не фреймворк, а один класс, которым будет пользоваться один человек. Ну два. Надо как-то трезво смотреть на реальность.
     
  24. MiksIr

    MiksIr Активный пользователь

    С нами с:
    29 ноя 2006
    Сообщения:
    2.339
    Симпатии:
    44
    igordata и прав и не прав одновременно
    Придумывать какие-то архитектурные сложности в угоду какой-то перспективе не нужно, это он прав. Если только это не академический проект, т.е. направленный на ваше обучение. Ибо если всегда исходить из "ща нагавнокожу, а когда гугл купит за 100500 мильонов - перепешу офигенно", то ничему не научишься никогда.
    А неправ, ибо не понимает, что все это зависит от уровня программиста, его опыта. Начиная с какого-то момента планка "излишеств" сдвигается. И то, что для кого-то тут излишество - для такого программиста - минимальная норма.
    Хорошо это или плохо? Дефицит реальных сеньоров в пхп говорит, что хорошо ;)
     
  25. Kutuz

    Kutuz Новичок

    С нами с:
    10 апр 2016
    Сообщения:
    15
    Симпатии:
    0
    при чем здесь мой фреймворк? и с чего вдруг взялась цифра людей использующий условно описанный компонент, а вдруг проект корпоративный? кто сказал что это вообще конечный класс в составе какого-то фреймворка отвечающий за базу данных? я же дал просто набросок, который расширяет версию автора в рамках его же класса.
    пара методов set\/get default, я назвать архитектурной сложностью не смогу, это просто заглушка, можно делать заглушки постоянно, но правильно что в меру и без излишеств.