Совместное использование 1 соединений mysql между несколькими экземплярами класса БД - PullRequest
1 голос
/ 30 октября 2011

Я немного застрял в следующей проблеме: я хотел бы, чтобы все мои классы использовали только одно соединение 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.
}

Это не работает должным образом (= возвращает только одного пользователя вместо всех), так как query () в User перезаписывает «mysqli_result var» от Admin новым запросом (что, очевидно, имеет смысл, поскольку есть только один экземпляр БД, так как это синглтон). Так что из-за этой вложенности запросов синглтон не будет работать.

То, что я хотел бы сделать сейчас, - это хранить соединение в отдельном одноэлементном классе и создавать новые классы БД для запросов и т. Д. На ходу (в которых будет использоваться соединение из одноэлементного класса). В основном как то так:

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

Но я просто не могу понять это. Если я вызову parent :: __ construct () из БД, это создаст новый экземпляр Connection, который, очевидно, не то, что я ищу. Клонирование соединения, очевидно, тоже не будет работать. Как я могу сказать БД использовать ссылку mysqli из Соединения без фактического создания нового объекта Соединения?

Надеюсь, я более или менее четко изложил свою проблему :) Как уже упоминалось выше, я несколько застрял и до сих пор не нашел полезных советов

Ответы [ 2 ]

0 голосов
/ 30 октября 2011
<?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'];
}

?>
0 голосов
/ 30 октября 2011

Подожди минутку. Метод 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;
}
...