Scope error - Call to a member function prepare() on a non-object

前端 未结 2 1300
無奈伤痛
無奈伤痛 2020-12-22 09:39

So the scenario is simple. I use class that does something in database but in that class I call another class that also does something in DB.

Thanks, include_once ch

相关标签:
2条回答
  • 2020-12-22 10:09

    The scope of $DB isn't within the classes because you haven't passed it into the classes. At the moment its just floating around in global scope, but not within the scope of your classes.

    You need to add $DB into the Log class, you can do this as a static variable like so inside your db_config.php

    Log::$DB = $DB;
    

    And use like this in your class

    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();
            }
        }
    }
    
    0 讨论(0)
  • 2020-12-22 10:11

    You used include_once "db_config.php"; instead of include "db_config.php";.

    As I understand from your code, each time you include db_config.php, you will create the database object $DBH.

    Since you put it as include_once, it will only run db_config.php once, and in the log class when you try to include it, it will not run - since it has already been included in the Add method.

    To improve on this, you should create a class that solely manages (or encapsulate) the PDO object. You can simply create a Singleton class that returns the PDO object, include the class once at the top, and fetch the object where ever you are in the code.

    Example:

    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;
        }
    
    }
    

    Log Class:

    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();
            }
        }
    }
    

    Usage:

    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();
        }
    }
    
    0 讨论(0)
提交回复
热议问题