Добрый вечер. Помогите плз исправить ошибку Fatal error: Uncaught Error: Call to undefined method DataBase:: prepare() in W:\domains\qqq.ru\application\core\DataBase.php:74 Stack trace: #0 W:\domains\qqq.ru\application\core\Model.php(32): DataBase->select('*', 'fThemes', 'id=:id', Array, NULL, NULL, NULL, NULL) #1 W:\domains\qqq.ru\application\models\Theme_Model.php(12): Model->getData() #2 W:\domains\qqq.ru\application\controllers\Theme_Controller.php(18): Theme_Model->getSingleData() #3 W:\domains\qqq.ru\application\core\Route.php(52): Theme_Controller->show_action() #4 W:\domains\qqq.ru\application\load.php(16): Route::start() #5 W:\domains\qqq.ru\index.php(3): require_once('W:\\domains\\qqq....') #6 {main} thrown in W:\domains\qqq.ru\application\core\DataBase.php on line 68 Если в методе getConnection() просто возвращать return new self; то все работает, но тогда создается несколько объектов var_dump в файле Model.php возвращает object(DataBase)#5 (0) { } DataBase.php PHP: <?php class DataBase { const host = 'localhost'; const dbname = 'cms'; const user = 'mysql'; const password = 'mysql'; private static $dbPDO; /** * DataBase constructor. */ private function __construct() { try { self::$dbPDO = new PDO('mysql:host='.self::host.';dbname='.self::dbname, self::user, self::password); self::$dbPDO->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING); } catch (Exception $e) { echo 'Connection failed '.$e->getMessage(); } //return self::$dbPDO; } /** Singleton * @return DataBase */ public static function getConnection() { if(is_null(self::$dbPDO)) { self::$dbPDO = new self(); } return self::$dbPDO; } /** * @param string $fields * @param string $table * @param string $where * @param array $prepare_params * @param string $limit * @param string $order * @param string $rightTable * @param string $condition * @return array * @throws Exception */ public function select($fields = '*', $table, $where, $prepare_params, $limit, $order, $rightTable, $condition) { $array = []; $sql = 'SELECT ' . $fields . ' FROM ' . $table; if ($rightTable != null) { $sql .= ' LEFT JOIN ' . $rightTable . ' on ' . $condition; } if ($where != null) { $sql .= ' WHERE ' . $where; } if ($order != null) { $sql .= ' ORDER BY ' . $order; } if ($limit != null) { $sql .= ' LIMIT ' . $limit; } $sth = self::$dbPDO->prepare($sql); $sth->execute($prepare_params); if ($sth->rowCount() == 0) { throw new Exception('SQL request returned 0 rows'); } else { while ($row = $sth->fetch(PDO::FETCH_ASSOC)) { array_push($array, $row); } return $array; } } Model.php PHP: <?php class Model { protected $pdo; public static $lastInsertId; protected static $fields = '*'; protected static $table; protected static $rightTable = null; protected static $rows = 'id=:id'; protected static $prepare_params = null; protected static $order = null; protected static $where = null; protected static $condition = null; protected static $limit = null; /** * Connection to database */ protected function connectToDB() { $this->pdo = DataBase::getConnection(); var_dump($this->pdo); } /** * @return string|array */ protected function getData() { try { $this->connectToDB(); $data = $this->pdo->select(self::$fields, self::$table, self::$where, self::$prepare_params, self::$limit, self::$order, self::$rightTable, self::$condition); } catch (Exception $e) { $data = $e->getMessage(); } return $data; } Спасибо
я понял что не существует метод, а почему если вместо этого PHP: public static function getConnection() { if(is_null(self::$dbPDO)) { self::$dbPDO = new self(); } return self::$dbPDO; } просто сделать PHP: public static function getConnection() { return new self; } работает. Т.е. в предыдущем коде объект не создается или что
Конструкт запускается один раз ПЕРЕД создание объекта. Кто тебя учил так делать синглтоны?) --- Добавлено --- PHP: class Helper { protected static $_instance; public static function _instance() { return self::$_instance = self::$_instance ?? new self(); } }
да там сям читал, твой код не помог( var_dump DataBase::getConnection возвращает object(DataBase)#5 (0) { }, если в return оставить только new self() работает, а var_dump так же возвращает object(DataBase)#5 (0) { }
@HeuPoH, попробуйте не выпускать экземпляр PDO за пределы класса, тем более что есть select (можно будет и др. методы добавить, если понадобятся).
Ты возвращаешь экземпляр класса Database, а пытаешься из него дёргать методы класса PDO. Естественно садишься в лужу. Вообще, это стремление делать над PDO свои классы, ничего полезного к нему не добавляющие - это глупость. А ещё глупость - пытаться программировать ООП, прочитав что-то там "там-сям" вместо нормальной книжки. Видно, что ни язык ни ООП ты не знаешь. По языку: https://www.ozon.ru/context/detail/id/139127353/, по ООП на php: https://www.ozon.ru/context/detail/id/33506422/ (поищи, обе книги можно и скачать)
Но почему, когда я возвращаю return new self; все работает? если через var_dump я вижу тот же объект DataBase? Спасибо за книги, да я ООП не знаю, но почему ты решил, что я вообще не знаю языка? --- Добавлено --- Спасибо за ответ
Потому что код так написан, что хрен в нём что поймёшь. Когда ты возвращаешь new self, срабатывает конструктор, который в поле $dbPDO записывает экземпляр PDO, а когда ты пытаешься изображать синглтон, ты туда рисуешь экземпляр своего дурацкого класса Знание языка предполагает знание, как в нём работают в том числе и классы. Заметь, не то, как правильно программировать ООП - это отдельная от языка история
Все работает, только через задний проход. Это уже не синглтон. Вы позволяете клонировать экземпляры своего класса на одном экземпляре PDO. У синглтона должен быть максимум один экземпляр. Максимум, потому что его можно сделать полностью статичным.