Я переключаю свой MVC на использование PDO (я знаю, просрочен). В прошлом мое приложение использовало следующую иерархию классов:
Database.class> Main.class> User.class
(каждый из которых распространяется на другой). Но перед созданием любого объекта было создано соединение mysql (mysql_connect). Как только соединение было открыто, я мог бы использовать Database.class в качестве класса-оболочки, через который выполнялись все мои запросы. Благодаря расширению запрос в User.class может быть выполнен просто путем вызова функции запроса ($ this-> query).
Используя PDO, я попытался подражать процессу, но обнаружил ошибки. Я создал одиночную функцию в Database.class:
function __construct() { $this->db = new PDO('mysql:host='.DB_HOST.';dbname='.DB_NAME.';charset=utf8', DB_USER, DB_PASSWORD); $this->db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $this->db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); } public static function getInstance() { if (!isset(self::$instance)){ $object = __CLASS__; self::$instance = new $object; } return self::$instance; } function query($qry,$params=NULL){ $qry = $this->db->prepare('SELECT * FROM users WHERE userID = :userID'); $qry->execute(array(':userID' => 1)); $results = $qry->fetchAll(PDO::FETCH_ASSOC); return $results; }
Затем в Main.class я получаю экземпляр:
function __construct() { $this->db = parent::getInstance(); }
Поэтому в User.class я пытаюсь позвонить
function __construct(){ parent::__construct(); } function test(){ return $this->db->query("test"); }
Поэтому я могу запускать любые запросы из объекта Main.class. Но если я пытаюсь запустить запросы из объекта User.class, я получаю сообщение об ошибке: «Вызов функции-функции-члена () для не-объекта» Другими словами, если User.class extends main, я должен иметь доступ к переменной $ db в Main из User.class (я вызываю конструктор для Main при создании объекта User). Отчасти проблема заключается в том, что Main.class создается ранее в приложении как свой собственный объект, я считаю, что создается два экземпляра PDO – вот почему он не работает через расширение (через второй объект, который также расширяет database.class)
Поэтому мой вопрос: есть ли способ сделать это возможным? Или мой лучший вариант использовать инъекции для каждого создаваемого объекта (потому что некоторые скрипты включают в себя несколько объектов, которые расширяют Main.class, которые каждый раз пытаются создать экземпляр PDO) и передать объект pdo в конструктор? Я бы предпочел не делать этого (чем меньше разница, тем лучше). Еще одним вариантом было бы использовать переменную STATIC, используемую всеми классами? Какой лучший метод? (дайте мне знать, если это сбивает с толку)
Я видел людей, использующих инъекцию для этого, и я видел примеры расширения класса оболочки pdo (но только один раз).
Благодаря! (Я люблю переполнение стека!)