2017-02-14 17 views
0

У меня проблема с шаблоном singleton PHP, особенно в отношении реализации оболочки mysqli.PHP Singleton Pattern для mysqli Wrapper

class DbHandler 
{ 

    private $mysqli; 
    private $query; 
    private $results = array(); 
    private $numRows = 0; 

    public static $instance; 

    public static function getInstance() { 
     if (!isset(self::$instance)) { 
      self::$instance = new DbHandler; 
     } 
     return self::$instance; 
    } 

    public function __construct() { 
     $this->mysqli = new mysqli("127.0.0.1", "root", "", "improved_portal"); 
     if ($this->mysqli->connect_error) { 
      die($this->mysqli->connect_error); 
     } 
    } 

    public function query($statement) { 
     if ($this->query = $this->mysqli->query($statement)) { 
      foreach ($this->query as $value) { 
       $this->results[] = $value; 
      } 
      $this->numRows = $this->query->num_rows; 
      return $this; 
     } 
    } 

    public function getResults() { 
     return $this->results; 
    } 

    public function getNumRows() { 
     return $this->numRows; 
    } 

} 

Когда я иду использовать класс в других объектах, у меня, похоже, проблема с результатами. Вместо создания нового объекта каждый раз с уникальными $ results, кажется, я создаю копии исходного объекта. Например ...

$object1 = DbHandler::getInstance(); 
$object1->query("SELECT * FROM table_a")->getResults(); 

$object2 = DbHandler::getInstance(); 
$object2->query("SELECT * FROM table_b")->getResults(); 

$ object2 содержит результаты обоих запросов, что явно не то, что я ожидаю. Функция запроса явно проходит через результаты второго запроса и добавляет их в свойство $ results первого объекта. Как я могу вызвать новый экземпляр класса DbHandler, чтобы каждый объект содержал уникальные свойства?

+0

Вы должны сделать свой '__construct()' метод и '$ instance' свойство частного и использовать только статический' деЫпзЬапса() 'метод вашего класса для создания объекта. –

+0

'$ this-> results' должно быть __cleared__ каждый раз –

ответ

0

Прежде всего - это не одноцветный узор. Как ваш __construct Публичная я могу это сделать:

$conn1 = new DbHandler(); 
$conn2 = new DbHandler(); 
$conn3 = new DbHandler(); 

Чтобы предотвратить это - __construct должны быть защищены/частным.

Второй - каждый раз, когда вы вызываете query() с того же объекта, эта функция добавляет результаты в results. И это свойство results используется для всех запросов без очистки. Разумеется, он сохранит все предыдущие значения. Функция должна быть переписана как:

public function query($statement) { 
    // clear result from previous function call 
    $this->results = array(); 

    if ($this->query = $this->mysqli->query($statement)) { 
     foreach ($this->query as $value) { 
      $this->results[] = $value; 
     } 
     $this->numRows = $this->query->num_rows; 
     return $this; 
    } 
}