Таким образом, сценарий прост. Я использую класс, который что-то делает в базе данных, но в этом классе я вызываю другой класс, который также делает что-то в БД.
Спасибо, 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(); } }
Вы использовали include_once "db_config.php";
вместо include "db_config.php";
,
Как я понимаю из вашего кода, каждый раз, когда вы включаете db_config.php
, вы создадите объект базы данных $DBH
.
Поскольку вы добавили его как include_once
, он будет запускать только db_config.php один раз, а в классе журнала, когда вы попытаетесь его включить, он не будет запущен – поскольку он уже включен в метод Add.
Чтобы улучшить это, вы должны создать класс, который только управляет (или инкапсулирует) объект PDO. Вы можете просто создать класс Singleton, который возвращает объект PDO, включить класс один раз вверху и извлечь объект, где бы вы ни находились в коде.
Пример:
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(); } } }