Ошибка области - вызов функции-члена 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('Y-m-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();
}
}
2 ответа
Ты использовал 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('Y-m-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('Y-m-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();
}
}
}