PHP OO数据库无法';拿不到mysqli

PHP OO数据库无法';拿不到mysqli,php,database,oop,mysqli,Php,Database,Oop,Mysqli,我最近在使用一个数据库类时遇到了一个问题,我的类在获取mysqli时遇到了一些问题。这里有几节课要上,请耐心听我说。有一个名为Manager的类连接到数据库并进行设置,然后实例化一个名为Business的新类并传入数据库,然后在代码执行中运行一个Manager方法,要求Business将一些数据保存到数据库,这就是问题所在。 数据库类如下,敏感信息已编辑: namespace Lib; define('_DBHOST', 'localhost'); define('_DBUSER', '***

我最近在使用一个数据库类时遇到了一个问题,我的类在获取mysqli时遇到了一些问题。这里有几节课要上,请耐心听我说。有一个名为Manager的类连接到数据库并进行设置,然后实例化一个名为Business的新类并传入数据库,然后在代码执行中运行一个Manager方法,要求Business将一些数据保存到数据库,这就是问题所在。 数据库类如下,敏感信息已编辑:

namespace Lib;

define('_DBHOST', 'localhost');
define('_DBUSER', '***');
define('_DBPASS', '***');
define('_DBNAME', '***');

class DB_Conn {
    protected $DB;

    function __construct() { 
       $this->connect();
    }

    protected function connect() {
        $this->DB = new \mysqli(_DBHOST, _DBUSER, _DBPASS, _DBNAME);         

        if($this->DB == false) {
           die(mysqli_connect_error());
        } 
    }

    function __destruct() {
        $this->DB->close();
    }

    function getDB() { 

        if (!isset($this->DB)) { echo "connecting...<br />";
            $this->connect();
        }          
        return $this->DB;

    }

}
这是商务舱

namespace Lib;    
class Business {
    var $mysqli;
    var $database;
    function __construct($mysqli) {
        $this->database = $mysqli;          
    }

    function addBusiness($data)
    {           
        $stmt = $this->database->prepare("INSERT INTO reboot_business(business_name) VALUES (?)");
        //Here $stmt is NULL

        //Bind the values from the array to the prepared statement
        $stmt->bind_param('s', $data['values']['name']);            

        //Execute the prepared statement and display any error
        if (!$stmt->execute()) {
            var_dump($stmt->error);
            //exit();
            return false;
        } else {
            //Succcess add ID to variable    
            return true;
        }                       
    }
}
我仔细检查了SQL语句,结果很好,实际错误发生在上面的业务类中,我使用了mysqli->prepare函数。错误是:

警告:mysqli::prepare():无法获取mysqli
致命错误:对非对象调用成员函数bindParam()

我还检查了$stmt变量,该变量为NULL,因此问题似乎在于获取mysqli

我是错过了什么,还是我做错了

通过在业务构造函数中创建DB_Conn类的新实例,我可以让它工作,但这似乎不正确,或者我应该这样做,而不让Manager类处理DB?实际上,如果Manager类在不需要DB的情况下做这些事情,那么从OO的角度来看,这是错误的吗

希望我有道理,并感谢任何帮助

在做了一些额外的调试之后,我发现在业务构造函数中,mysqli都很好,没有错误,看起来它正在工作

编辑:

然而,在我的addBusiness()方法中,我得到了一些有趣的输出,我正在使用var_dump($this->database),我得到了大约16个错误:警告:var_dump():还不允许访问属性
我的代码中没有任何循环,这使得它出现了16次wierd,然后当它最终工作时,var_dump报告所有空值:
object(mysqli){12(19){[“受影响的行”]=>null[“客户端信息”]=>null[“客户端版本”]=>int(50010)[“连接错误”]=>int(0)[“连接错误”=>null[“错误”=>null[“错误”=>null[“错误”=>null=>null[“error”]=>NULL[“error\u list”]=>NULL[“field\u count”]=>NULL[“host\u info”]=>NULL[“info”]=>NULL[“insert\u id”]=>NULL[“server\u info”]=>NULL[“server\u version”]=>NULL[“sqlstate”]=>NULL[“protocol\u version”=>NULL[“thread\u id”]=>NULL[“warning\u count”=>NULL}

问题在于数据库属性如何在构造函数中保持良好状态,但在方法中却是空的。您知道为什么会将其清空或设置为null吗?

错误是因为您试图访问数据库连接的未设置变量

在业务构造函数中声明:

$this->database = $mysqli;        
但是,您尝试访问MYSQLi连接,如下所示:

$stmt = $this->mysqli->prepare()
您需要引用已建立的数据库变量,以便:

$stmt = $this->database->prepare()

问题是$database变量中的“DB_Conn”在Manager中的uu construct()语句结尾处超出范围。这将触发DB_Conn中的u destruct(),从而关闭数据库

答案是:

在Manager->database属性中保存“_DB_Conn_”对象,而不是从_DB_Conn_对象保存“PDO连接”

新经理级别:

class Manager {
    public $mysqli;
    private $businessMan;

    public function __construct() {
        //Grab database and connect to it
        $database = new \Lib\DB_Conn();
        $this->mysqli = $database->getDB();

        $this->businessMan = new \Lib\Business($this->mysqli);
    }       

    public function submitForm($data) { 

            //Save Data
            if($this->businessMan->addBusiness($data)) {
                echo "Yay";
            } else {
                echo "NO!";
            }

    }
}
说明:

错误在“Manager”的构造函数中

public function __construct() {
    //Grab database and connect to it
    $database = new \Lib\DB_Conn();
    $this->mysqli = $database->getDB();

    $this->businessMan = new \Lib\Business($this->mysqli);
}


class DB_Conn {

    ...

    function __destruct() {
        var_dump(__CLASS__, __METHOD__, 'this should not happen until the end!');
        $this->DB->close();
    }
我重新创建了您的代码并运行了它。我遇到了以下错误:

Couldn't fetch mysqli in P:\developer\xampp\htdocs\testmysql\Q28550480\Business.php on line 15
这让我得出这样的评论:

  • 正在尝试使用关闭的数据库

这可能是通过引用传入$mysqli的问题吗?例如,使用&我现在没有通过引用传入mysqli,我尝试了一下,但出现了另一个错误。您使用的是mysqli还是PDO?如果是mysqli,那么应该使用“bind_param”语句,而不是PDO bindParam语句。这是mysqli,我把它改回bind_param,但仍然没有错误,我只是做了一些挖掘,你不能在mysqli中使用命名参数,所以我把它去掉了。你检查过“$database”是有效的“mysqli对象”吗?我会从创建它的地方开始用var_dump检查它,然后继续检查。我还会检查任何错误消息在每个阶段都会出现错误。感谢我的快速响应,这是一个愚蠢的错误,我现在已经纠正了,但问题仍然存在。我编辑了上面的代码以反映这一点。警告:mysqli::prepare():无法获取mysqli,此错误会导致bind_param函数出现致命错误:致命错误:对中的非对象调用成员函数bind_param()。是的,我认为这是由于bind param。请尝试以下操作:$stmt->bindParam(:business_name,$data['values']['name',PDO::param_STR);并将prepare语句从?更改为使用:business_namePer php手册:对于使用问号占位符的prepare语句,这将是参数的1索引位置。因此“必须是1。或者将其切换为使用:参数名称恐怕也不起作用,仍然会出现相同的错误,关于获取mysqli的警告,然后是bind_param的致命错误。关于准备好的陈述和问号的有用说明。太棒了,非常感谢你解决了这个问题,在这个过程中我学到了一些新东西。我认为,当我将$database变量放入“Manager”中的mysqli属性时,就可以了。再次感谢
Couldn't fetch mysqli in P:\developer\xampp\htdocs\testmysql\Q28550480\Business.php on line 15