dongmale0656 2011-10-30 08:53 采纳率: 100%
浏览 22
已采纳

在DB类的多个实例之间共享1个mysql连接

I'm a little bit stuck with the following problem: I would like all my classes to just use 1 single mysqli connection. I don't particulary like dependency injection (it seems unelegant to me to pass the connection around via the constructor) so I implemented a singleton. This works well except for the following problem:

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.
}

This doesn't work as expected (=Returns just one user instead of all of them) as the query() in User overwrites the "mysqli_result var" from Admin with the new query (which obviously makes sense as there is only one instance of DB since it's a singleton). So due to this nesting of queries a singleton won't work.

What I would like to do now is to store the connection in a separate singleton class and create new DB classes for querying etc. on the go (which would use the connection from the singleton class). Basically something like this:

class DB extendes Connection { .... } // Called as $DB = new DB in other classes
class Connection extends mysqli { .... } // This is a singleton

But I just can't figure it out. If I call parent::__construct() from DB it will create a new Connection instance which obviously isn't what I'm looking for. Cloning Connection obviously won't work either. How can I tell DB to use the mysqli link from Connection without actually creating a new Connection object?

I hope I layed out my problem more or less clearly :) As mentioned above I'm somewhat stuck and I didn't find any helpfull hints so far

  • 写回答

2条回答 默认 最新

  • douyin2435 2011-10-30 10:38
    关注
    <?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'];
    }
    
    ?>
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 stata安慰剂检验作图但是真实值不出现在图上
  • ¥15 c程序不知道为什么得不到结果
  • ¥40 复杂的限制性的商函数处理
  • ¥15 程序不包含适用于入口点的静态Main方法
  • ¥15 素材场景中光线烘焙后灯光失效
  • ¥15 请教一下各位,为什么我这个没有实现模拟点击
  • ¥15 执行 virtuoso 命令后,界面没有,cadence 启动不起来
  • ¥50 comfyui下连接animatediff节点生成视频质量非常差的原因
  • ¥20 有关区间dp的问题求解
  • ¥15 多电路系统共用电源的串扰问题