我创建了自己的数据库类来简化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
)。
有任何建议使这项工作?
非常感谢
答案 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;
}
}
<强>文档强>