PHP: class DB { private static $_db; public static function getDB() { if(is_null(self::$_db)) self::$_db = new DB; return self::$_db; } private function __construct() { $connect = new mysqli('localhost', 'root', '', 'mysite'); if(!$connect) die("ERROR!"); } public function query($sql) { self::$_db->query($sql); } private function __clone() {} } $obj = DB::getDB(); $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 Что за ошибка и как исправить, уже по разному пробовал. К базе подключается а метод не работает.
То есть название метода должно отличаться? Изменил Fatal error: Call to undefined method DB::query() in
PHP: class DB { private static $_db = null; private $connect; private function __construct() { $this->connect = new mysqli('localhost', 'root', '', 'mysite'); if(!$this->connect) die("ERROR!"); } public static function getDB() { if(is_null(self::$_db)) { $object = new DB; self::$_db = $object->connect; } return self::$_db; } public function query($sql) { self::$_db->query($sql); } private function __clone() {} } $obj = DB::getDB(); $obj->query("CREATE TABLE IF NOT EXISTS table3('name text, surname text')"); вот так переписал, теперь ошибки нету, но и не выполняется запрос
У вас ошибка в запросе. И зачем вам в таком виде класса new DB вообще? Или оставляйте new DB и возвращайте его инстанс, а в query уже к connect обращайтесь. Или вообще выкидывайте new DB, конструкторы, query и делайте new mysqli
Какая ошибка в запросе? Вне класса работает этот запрос Выкинуть? Имеете ввиду без класса? Но я хочу с синглтоном разобраться
Синглтон базы данных нужен для добавления хоть какого-то функционала, в вашем последнем случае он ничего не добавляет. Как избежать ошибки в изначальном коде, вам много раз подсказали PHP: class DB { private static $_db; private $connetct; public static function getDB() { if(is_null(self::$_db))self::$_db=new DB; returnself::$_db; } privatefunction __construct() { $this->connect=new mysqli('localhost','root','','mysite'); if(!$this->connect)die("ERROR!"); } publicfunction query($sql) { return $this->connect->query($sql); } privatefunction __clone(){} } Но в таком виде этот синглтон бесполезен, если вам не нужно добавлять никакого функционала, то используйте прямо mysqli.
Ну функционал я буду добавлять, просто смысл мне было сразу много добавлять если даже один запрос не работает. Спасибо, теперь работает.
Синглетон в реалиях в основном применим в фасадных слоях приложения, используется в основном для "опорных точек" приложения,а эту часть я бы реализовал по крайней мере на статическом внедрении зависимостей, это обеспечит возможность расширения функционала в этой части, позволит тебе потом подменять объекты, если способы работы с БД изменятся, интерфейс останется, поэтому можно подумать о обобщенном интерфейсе для таких случаев Код (Text): class DB { protected static $_default; protected $_connection; public static function getDefault(){ if(is_null(self::$_db))self::$_db=new DB(['localhost','root','','mydb']); returnself::$_db; } public static function setDefault(DB $db){ self::$_default = $db; } public function __construct($options){ $this->_connection = new mysqli($options[0],$options[1],$options[2],$options[3]); if(!$this->_connection)die("ERROR!"); } public function query($sql) { return $this->_connection->query($sql); } // bonus public static function __callStatic($m,$a){ return call_user_func_array([self::getDefault(),$m],$a); } private function __clone(){} }
я прост не считаю правильным заранее закладывать механизмы, которые могут не понадобиться вообще никогда.
Эмм. Да. Всю систему одного файла кверек в БД. Да. Да. Переделывать. Потом. Может быть. Возможно. Может и нет. Да, придётся отрефакторить четыре метода в одном файле. В противном случае можно всё заранее адаптировать под любые другие универсальности, которые в потенциале могут быть. А это пипец. В то время, как рефакторинг одного простого файла класса, который должен быть написан простым языком, без врзырвного кода - это быстро и просто. А если вы пишете сложно, если у вас длинные методы, не разбитые на подфункции - вы уже что-то делаете не так. Уже. И это уже надо исправлять до того, как вы вообще будете или не будете закладывать универсальность в ваш класс.
Во фреймворках это уже понадобилось. А у тебя ещё не популярный фреймворк, и даже не фреймворк, а один класс, которым будет пользоваться один человек. Ну два. Надо как-то трезво смотреть на реальность.
igordata и прав и не прав одновременно Придумывать какие-то архитектурные сложности в угоду какой-то перспективе не нужно, это он прав. Если только это не академический проект, т.е. направленный на ваше обучение. Ибо если всегда исходить из "ща нагавнокожу, а когда гугл купит за 100500 мильонов - перепешу офигенно", то ничему не научишься никогда. А неправ, ибо не понимает, что все это зависит от уровня программиста, его опыта. Начиная с какого-то момента планка "излишеств" сдвигается. И то, что для кого-то тут излишество - для такого программиста - минимальная норма. Хорошо это или плохо? Дефицит реальных сеньоров в пхп говорит, что хорошо
при чем здесь мой фреймворк? и с чего вдруг взялась цифра людей использующий условно описанный компонент, а вдруг проект корпоративный? кто сказал что это вообще конечный класс в составе какого-то фреймворка отвечающий за базу данных? я же дал просто набросок, который расширяет версию автора в рамках его же класса. пара методов set\/get default, я назвать архитектурной сложностью не смогу, это просто заглушка, можно делать заглушки постоянно, но правильно что в меру и без излишеств.