我有点陷入以下问题:我希望我的所有课程都只使用1个单独的mysqli连接。我并不特别喜欢依赖注入(通过构造函数传递连接对我来说似乎不太优雅)所以我实现了一个单例。除了以下问题之外,这很有效:
class Admin {
private $DB;
public function __construct() {
$this->DB = new DB::get_instance();
}
public function get_all_users() {
$this->DB->query('SELECT `email` FROM `users`');
while ($row = $this->DB->result->fetch_row()) { $users[] = new User($row[0]); }
return $users;
}
}
class User {
private $DB;
public function __construct($email = FALSE){
$this->DB = new DB;
if ($email) {
$this->load($email);
}
}
public function load($email){
$this->DB->query('SELECT * FROM `users` WHERE email = "'.$this->email.'";'); // Problem!
// etc.
}
这不能按预期工作(=只返回一个用户而不是所有用户),因为User中的query()用新的查询覆盖Admin的“mysqli_result var”(这显然是有意义的,因为只有DB的一个实例,因为它是一个单例)。因此,由于查询的嵌套,单例将无法工作。
我现在想要做的是将连接存储在一个单独的单例类中,并在移动中创建用于查询等的新数据库类(这将使用来自单例类的连接)。基本上是这样的:
class DB extendes Connection { .... } // Called as $DB = new DB in other classes
class Connection extends mysqli { .... } // This is a singleton
但我无法弄明白。如果我从DB调用parent :: __ construct(),它将创建一个新的Connection实例,这显然不是我正在寻找的。克隆连接显然也无法正常工作。如何告诉DB使用Connection中的mysqli链接而不实际创建新的Connection对象?
我希望我或多或少地清楚地解决了我的问题:)如上所述,我有些卡住了,到目前为止我没有找到任何有用的提示
答案 0 :(得分:0)
等一下。 query()
方法返回Result
个对象。你为什么使用DB->result
?无论你如何组织物体,你都会碰到同一面墙。
您应该迭代query()
的结果,例如
public function get_all_users() {
$result = $this->DB->query('SELECT `email` FROM `users`');
while ($row = $result->fetch_row()) { $users[] = new User($row[0]); }
return $users;
}
答案 1 :(得分:0)
<?php
//Create a registry class to hold objects that traverse all the classes
Class Registry {
private $vars = array();
public function __set($index, $value){$this->vars[$index] = $value;}
public function __get($index){return $this->vars[$index];}
}
//Your singleton db class
class db{
private static $instance = NULL;
private function __construct() {
}
public static function getInstance($DBHOST,$DBDB,$DBUSER,$DBPASS) {
if (!self::$instance){
self::$instance = new PDO("mysql:host=".$DBHOST.";dbname=".$DBDB, $DBUSER, $DBPASS);
self::$instance->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
return self::$instance;
}
private function __clone(){}
}
//assign the database object to the registry, within your initialization
$registry = new registry;
$registry->db = db::getInstance(DBHOST,DBDB,DBUSER,DBPASS);
$registry->router = new router($registry);
$registry->users = new users($registry);
//Then add to your class constructors to have that connection available
protected $registry;
function __construct($registry){
$this->registry=$registry;
}
//.....
$result = $this->registry->db->query('SELECT ...')->fetchAll(PDO::FETCH_ASSOC);
foreach($result as $key=>$val){
$this->registry->$val['setting']=$val['value'];
}
?>