范围错误-在非对象上调用成员函数prepare() [英] Scope error - Call to a member function prepare() on a non-object

查看:70
本文介绍了范围错误-在非对象上调用成员函数prepare()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以场景很简单.我使用的类在数据库中执行某些操作,但在该类中,我调用了另一个在数据库中也执行某些操作的类.

谢谢,include_once已更改为include,并且可以使用!

这就是我得到的:

致命错误:调用成员函数 对非对象的prepare()->第20行的 mLog.php

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

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

解决方案

您使用的是include_once "db_config.php";而不是include "db_config.php";.

据我从代码中了解,每次包含db_config.php时,您都会创建数据库对象$DBH.

由于将其设置为include_once,因此它将仅运行db_config.php一次,并且在尝试包含它时在日志类中将使其不运行-因为它已经包含在Add方法中. /p>

要对此进行改进,您应该创建一个仅管理(或封装)PDO对象的类.您可以简单地创建一个返回PDO对象的Singleton类,将该类放在顶部一次,然后在代码中的任何位置获取该对象.

示例:

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

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 changed to include and it works!

This is what I get:

Fatal error: Call to a member function prepare() on a non-object -> mLog.php on line 20

I use db_config.php to create PDO object and then include it in my classes.

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

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

second class that uses first class (fragment because it's big and has many functions)

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

解决方案

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

这篇关于范围错误-在非对象上调用成员函数prepare()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆