我是OOP(PHP)的新手,刚刚遇到了设计模式 - singleton
。
我找到了一个使用mysqli(单例类)的DB类。我已为其添加了一些自定义方法(insert_id()
,query()
,fetch_result()
等。
然后我创建了一个名为UserTools
的新类,我想扩展数据库类以使用我之前创建的方法(query()
,fetch_result()
等)。
但是我得到了这个错误:
致命错误:从(...)中的无效上下文调用私有Database :: __ construct() 当我尝试创建新类的实例(用户工具)时。
我该怎么办?这是一个正确的结构吗?
答案 0 :(得分:1)
据我了解,只有protected
和public
方法和变量通过扩展而非私有方式继承。尝试将您的方法/变量从private
更改为protected
。所有人都可以看到public
个。
有关详细信息,请参阅:PHP Visibility (Manual)
修改强>
了解Singleton模式。它被称为“单例”,因为只需要一个类的实例。因此,大多数实现单例模式的类将构造函数定义为private,以限制您创建多个。
要创建单例的实例,大多数类定义某种getInstance
静态方法,它是公共的。此公共方法调用私有构造函数,该构造函数可能设置标志,指示该类已被实例化,以防止进一步尝试实例化该类。 getInstance
方法返回调用构造函数的结果,实际上是类的实例。
答案 1 :(得分:1)
有几种方法可以达到你想要的效果。
一个是:
class UserTools {
private $db;
function __construct() {
$this->db = Database::db_connect();
}
function login() { /* ... */}
}
虽然最好直接将数据库实例传递给构造函数,如下所示:
class UserTools {
private $db;
function __construct($db) {
$this->db = $db;
}
function login() { /* ... */}
}
// Usage
$userTools = new UserTools(Database::db_connect());
如果你真的很懒,你可以修改你的数据库类并使构造函数公开:
class Database {
/* ... */
public function __construct(){/* ... */}
/* ... */
}
class UserTools extends Database {/* ... */}
但我真的不鼓励你使用后者。这是非常糟糕的代码,从逻辑的角度来看它没有意义。您的UserTools类使用数据库实例。 不数据库。
答案 2 :(得分:0)
你可以写点像
class UserTools extends DB {
....
}
PHP中继承的一个简单示例:
class A {
public $a;
public function set_a($new_a) { $this->a = $new_a; return $this; }
public function get_a() { return $this->a; }
}
class B extends A {
public $b;
public function set_b($new_b) { $this->b = $new_b; return $this; }
public function get_b() { return $this->b; }
}
$objb = new B();
$objb->set_a("Some Value")->get_a(); //Some Value
答案 3 :(得分:0)
在大多数情况下,单例模式通过将构造函数定义为私有(即private function __construct()
)来防止实例化Singleton类。
因此,如果您尝试实例化您的自定义类或您正在扩展的原始类,您将收到上面的消息。您应该创建一个不同的类,或者定义并将您的函数用作静态函数(例如public static function query($sql, $dbconnection)
)。