我为PDO创建了一个单例模式,问题是当我使用它时,我有一个无限循环,例如,这样做:
$db=Db::fetch_instance();
$product = $db->query(<query>);
我有这个错误:
Fatal error: Maximum function nesting level of '100' reached, aborting!
我的课程就是这个:
class Db {
//START OF SINGLETON PATTERN
private static $PDOInstance;
public static function fetch_instance() {
try {
if(empty(self::$PDOInstance)){
self::$PDOInstance = new Db();
}
return self::$PDOInstance;
} catch (Exception $e) {
<something>
}
}
private function __construct() {
return new PDO("something");
}
//START OF DECORATOR PATTERN
public function beginTransaction() {
.......
}
public function query($statement) {
return self::$PDOInstance->query($statement);
}
........
为什么这个循环?,我没有看到任何循环。
答案 0 :(得分:4)
错误很明显,您的方法query
正在调用自己。
public function query($statement) {
return self::$PDOInstance->query($statement);
}
这是因为您的单身人士有错,您应该将代码更改为:
public static function fetch_instance() {
try {
if(empty(self::$PDOInstance)){
self::$PDOInstance = new PDO("something");
return self::$PDOInstance;
}
} catch (Exception $e) {
<something>
}
}
private function __construct() {
}
注意,构造函数不是要返回任何内容,而是将self::$PDOInstance
分配给新Db
对象的实例!
<强>更新强>
顺便说一句,这里更接近你想做的事情:
class Db {
// START OF SINGLETON PATTERN
private static $instance;
private $PDOInstance;
public static function fetch_instance() {
try {
if (empty(self::$PDOInstance)) {
self::$instance = new Db();
}
return self::$instance;
} catch (Exception $e) {
// <something>
}
}
private function __construct() {
return $this->PDOInstance = new PDO("something");
}
// START OF DECORATOR PATTERN
public function beginTransaction() {
// .......
}
public function query($statement) {
return $this->PDOInstance->query($statement);
}
}
$PDOInstance
是私有的并绑定到您的单身,$instance
是静态的,并且将包含Db
类的唯一实例。您的构造函数负责初始化您的$PDOInstance
,然后您可以将其用作$this->PDOInstance
答案 1 :(得分:2)
__ construct()不应该有返回值。
将其删除,并将fetch_instance()
改为:
public static function fetch_instance()
{
if (!self::$PDOInstance) {
self::$PDOInstance = new PDO();
}
return self::$PDOInstance;
}
答案 2 :(得分:0)
你的单身人士模式是错误的。如果希望类“Db”的实例为单例,则应该执行的操作是将Db::fetch_instance()
中唯一的“Db”实例存储到静态私有属性中。然后,此实例应具有PDO的实例。
class Db {
//START OF SINGLETON PATTERN
private static $dbInstance;
private $PDO;
public static function fetch_instance() {
try {
if(empty(self::$dbInstance)){
self::$dbInstance = new Db();
}
return self::$dbInstance;
} catch (Exception $e) {
<something>
}
}
private function __construct() {
$this->PDO = new PDO("something");
}
//START OF DECORATOR PATTERN
public function beginTransaction() {
.......
}
public function query($statement) {
return $this->PDO->query($statement);
}
........
请注意,确实没有必要使用单身人士。
总的来说,单身人士越来越被视为反模式。它们确实使代码严重可测,应该避免使用。
第二:PHP中总有多个实例,因为每个请求都在它自己的变量空间内运行。因此每个并发请求有一个实例,而不是每个服务器一个实例。这意味着所有这些实例同时连接到数据库。
第三:PHP中的mysql扩展阻止程序多次使用相同的凭据连接到同一个数据库。
第四:虽然目前可能没有需要,但有时会有多个数据库在同一时间。这是将数据库连接创建为单例的时间最多的时间。
所以我真的建议不要使用单例模式进行数据库连接。你什么都得不到,但却失去了很多。