用于mysqli Wrapper的{{4}模式

时间:2017-02-14 17:48:59

标签: php class oop singleton

我遇到了PHP单例模式的问题,特别是关于实现mysqli包装器的问题。

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类的新实例,以便每个对象都包含唯一的属性?

1 个答案:

答案 0 :(得分: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;
    }
}