php Возвращает FALSE для фабричного метода синглтона, если не удается создать соединение с базой данных - PullRequest
2 голосов
/ 31 января 2012

У меня есть класс, расширяющий mysqli.Он следует одноэлементному шаблону, поэтому у меня есть статический метод для извлечения общего экземпляра класса.

После вызова self::$instance = new self я полагаю, что self :: $ instance должен быть FALSE или NULL, если __construct не может установить соединение, но это не так.

Функция __construct вызывает ПРЕДУПРЕЖДЕНИЕ: Warning: mysqli::mysqli(): (HY000/2002): Can't connect to local MySQL server through socket etc.

Но экземпляр self :: $ создается как экземпляр класса BaseDatos.

Какя должен обнаружить сбой в соединении и вернуть FALSE по заводскому методу?

class BaseDatos extends mysqli {

    //singleton, instancia compartida
    private static $instance = null;    
    private $user = "root";
    private $password = "root";
    private $db = "agendaeventos";
    private $dbHost = "localhost";

    public static function getInstance() {
        if (!self::$instance instanceof self) {
            self::$instance = new self;
        }
        if (self::$instance) {
            return self::$instance;
        } else {
            return FALSE; //This is never called even when the connection is not created
        }
    }

    private function __construct() {
        parent::__construct($this->dbHost, $this->user, $this->password, $this->db);
        if (!mysqli_connect_errno()) {
            parent::set_charset('utf8');
        }
    }

}

Ответы [ 2 ]

2 голосов
/ 31 января 2012

Конструктор должен создать экземпляр, то есть он не может вернуть false или null.

Вы можете остановить создание экземпляра, вызвав исключение в своем конструкторе.Например, если вы не можете установить соединение с базой данных, сгенерируйте исключение, а затем перехватите его в getInstance(), чтобы вернуть false.

public static function getInstance() {
    if (self::$instance === null) {
        try {
            self::$instance = new self();
        } catch(Exception $e) {
            self::$instance = false;
        }
    }
    return self::$instance
}
private function __construct() {
    parent::__construct($this->dbHost, $this->user, $this->password, $this->db);
    if (!mysqli_connect_errno()) {
        parent::set_charset('utf8');
    } else {
         throw new Exception("Database connection");
    }
}

Однако я рекомендую вам не возвращатьfalse в getInstance(), но вместо этого просто сгенерируйте исключение и перехватите его там, где используется класс.

0 голосов
/ 31 января 2012

Вы должны изменить функцию getInstance, чтобы она выглядела следующим образом

public static function getInstance() {
    try {
      if (!self::$instance instanceof self) {
        self::$instance = new self;
      }
      return self::$instance;
    }
    catch {
        return false;
    }
}
...