Ошибка области – вызов функции-члена prepare () для объекта без объекта

Таким образом, сценарий прост. Я использую класс, который что-то делает в базе данных, но в этом классе я вызываю другой класс, который также делает что-то в БД.

Спасибо, include_once изменено, чтобы включить, и это работает!

Это то, что я получаю:

Неустранимая ошибка: вызов функции-члена prepare () для не-объекта -> mLog.php в строке 20

Я использую db_config.php для создания объекта PDO, а затем включаю его в свои классы.

db_config.php

try { $DBH = new PDO("mysql:host=$db_host;dbname=$db_name", $db_user, $db_pass); $DBH->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING); } catch (PDOException $e) { echo $e->getMessage(); } 

1-й класс mLog.php

 <?php class Log { public static function Add($action) { try { include_once "db_config.php"; $ip = $_SERVER['REMOTE_ADDR']; $time = date('Ym-d'); $values = array($ip, $action, $time); //ERROR NEXT LINE $STH = $DBH->prepare("INSERT INTO log (ip, action, time) VALUES (?, ?, ?)"); $STH->execute($values); $DBH = null; $STH = null; } catch (PDOException $e) { echo $e->getMessage(); } } } 

второй класс, который использует первый класс (фрагмент, потому что он большой и имеет много функций)

 public static function Add($catName, $catDescr = "", $catImgURL = "", $catSubLevel = 0, $catSubID = 0) { try { include_once "db_config.php"; include_once "mLog.php"; $values = array($catName, $catDescr, $catImgURL, $catSubLevel, $catSubID); $STH = $DBH->prepare("INSERT INTO cat (catName, catDescr, catImg, catSubLevel, catSubID) VALUES (?, ?, ?, ?, ?)"); $STH->execute($values); $DBH = null; $STH = null; //HERE IT IS Log::Add("Added category 111" . $catName); return true; } catch (PDOException $e) { echo $e->getMessage(); } } 

Solutions Collecting From Web of "Ошибка области – вызов функции-члена prepare () для объекта без объекта"

Вы использовали include_once "db_config.php"; вместо include "db_config.php"; ,

Как я понимаю из вашего кода, каждый раз, когда вы включаете db_config.php , вы создадите объект базы данных $DBH .

Поскольку вы добавили его как include_once , он будет запускать только db_config.php один раз, а в классе журнала, когда вы попытаетесь его включить, он не будет запущен – поскольку он уже включен в метод Add.

Чтобы улучшить это, вы должны создать класс, который только управляет (или инкапсулирует) объект PDO. Вы можете просто создать класс Singleton, который возвращает объект PDO, включить класс один раз вверху и извлечь объект, где бы вы ни находились в коде.

Пример:

DBAccess.php

 class DBAccess extends Singleton{ // there is a getInstance() method in the Singleton abstract class private $dbh; // The PDO object is created only once when the first getInstance() is called in Singleton. function __construct(){ try { $this->dbh = new PDO("mysql:host=$db_host;dbname=$db_name", $db_user, $db_pass); $this->dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING); } catch (PDOException $e) { echo $e->getMessage(); } } /** * Get the PDO object * @return object */ public static function getDBH(){ return self::getInstance()->dbh; } } 

Класс журнала:

 class Log { public static function Add($action) { try { $DBH = DBAccess::getDBH(); $ip = $_SERVER['REMOTE_ADDR']; $time = date('Ym-d'); $values = array($ip, $action, $time); $STH = $DBH->prepare("INSERT INTO log (ip, action, time) VALUES (?, ?, ?)"); $STH->execute($values); } catch (PDOException $e) { echo $e->getMessage(); } } } 

Применение:

include_once ( 'db_config.php'); include_once ( 'mLog.php');

 public static function Add($catName, $catDescr = '', $catImgURL = '', $catSubLevel = 0, $catSubID = 0) { try { $DBH = DBAccess::getDBH(); $values = array($catName, $catDescr, $catImgURL, $catSubLevel, $catSubID); $STH = $DBH->prepare("INSERT INTO cat (catName, catDescr, catImg, catSubLevel, catSubID) VALUES (?, ?, ?, ?, ?)"); $STH->execute($values); $DBH = null; Log::Add("Added category 111" . $catName); return true; } catch (PDOException $e) { echo $e->getMessage(); } } 

Объем $DB не входит в классы, потому что вы не передали его в классы. На данный момент он просто плавает в глобальном масштабе, но не входит в рамки ваших классов.

Вам нужно добавить $DB в класс Log , вы можете сделать это как статическую переменную, подобную этой внутри db_config.php

 Log::$DB = $DB; 

И используйте это в своем классе

 class Log { public static $DB; public static function Add($action) { try { include_once "db_config.php"; $ip = $_SERVER['REMOTE_ADDR']; $time = date('Ym-d'); $values = array($ip, $action, $time); $STH = self::$DBH->prepare("INSERT INTO log (ip, action, time) VALUES (?, ?, ?)"); $STH->execute($values); self::$DBH = null; $STH = null; } catch (PDOException $e) { echo $e->getMessage(); } } }