从另一个类访问数据库类

时间:2016-05-24 20:05:52

标签: php mysql class mysqli

我创建了自己的数据库类来简化MySQLi预处理语句,我试图在另一个类中访问它。

我已将数据库类扩展到我的配置文件类,并尝试在我的构造中运行select查询,并返回此错误:

  

致命错误:在第80行的/home/matt500b/dev2.csgoberry.com/includes/database.class.php中调用null上的成员函数prepare()

个人资料类构造:

public function __construct($username) {
    $params = parent::SELECT("SELECT users_info.*, users.username, users.lastOnline FROM users_info INNER JOIN users ON users.id = users_info.user_id WHERE users.username = ?", array('s', $username));
    $this->fname = (isset($params[0]['fname']) ? $params[0]['fname'] : null);
    /*More settings done here*/
}

但是,如果我先运行查询,那么将数据发送到构造中,如下所示:

$profileData = $db->SELECT('SELECT users_info.*, users.username, users.lastOnline FROM users_info INNER JOIN users ON users.id = users_info.user_id WHERE users.username = ?', array('s', $pid));
$pclass = new user_profile($profileData);

构造为:

public function __construct($params){
        $this->fname = (isset($params[0]['fname']) ? $params[0]['fname'] : null);
}

一切都很好。当然,数据库实例是使用$db = new database(HOST, USER, PASSWORD, DATABASE, DEBUG);调用的,其中我的数据库结构是:

public function __construct($db_host, $db_user, $db_pass, $db_name, $debug){
    $this->link = mysqli_connect($db_host, $db_user, $db_pass);
    mysqli_select_db($this->link, $db_name);
    $this->debug = $debug;
}

错误与此行有关:if ($stmt = $this->link->prepare($sql)) {并建议$ sql为null,但两个查询完全相同,除了它们的来源(parent::SELECT vs $db->SELECT)。

有任何建议使这项工作?

非常感谢

1 个答案:

答案 0 :(得分:2)

扩展类时,父类和子类都有构造函数,必须从子类调用父构造函数。如果父构造函数有参数,则必须a)在子构造函数中获取这些参数(最佳实践),或b)使用硬编码值(通常是不良实践)。

我假设a)您的父类在其构造函数中建立数据库连接,或者b)您将数据库连接传递给父类。如果是后者(b),则必须将该db连接作为子类的参数并手动唤起父构造函数,或者,从子类中的父构造函数重新实现任务。如果前者,(a),上述情况属实,但你从事的是不良做法。类构造函数不应该工作,除了它的祖先和类型化的构造函数参数之外,它不应该知道其他类。构造函数体中的new关键字通常是“代码味道”的标志 - 您创建了隐藏的依赖关系。

而不是使用数据库的类:

public function __construct ($username, $password) {
    // establish database connection using username and password
}

....

$myObject = new SomeClass('ausername', 'apassword');

......这样做:

$dbConnection = establishDbConnection($username, $password); // establish connection outside of the class
$myObject = new SomeClass($dbConnection); // pass in the connection into the object

^被称为“依赖注入”,是一个值得学习的主题!

以下是调用父构造函数的示例:

class A {
    private $a1 = null;
    public function __construct($arg1) {
        // do something with the args
        $this->a1 = $arg1;
    }
}

class B extends A {
    private $a2 = null;
    public function __construct($arg1, $arg2) {
        parent::__construct($arg1);
        $this->a2 = $arg2;
    }
}

<强>文档