Friday, 3 March 2017

mysqli - php Return FALSE on singleton factory method if data base connection can't be created



I have a class extending mysqli. It follows a singleton pattern so I have a static method to retrieve the shared instance of the class.



After calling self::$instance = new self I suppose self::$instance should be FALSE or NULL if __construct could not make the connection, but it is not.



The __construct function triggers a WARNING:
Warning: mysqli::mysqli(): (HY000/2002): Can't connect to local MySQL server through socket etc.



But self::$instance is created as an instance of BaseDatos class.




How should I detect a failure in the connection and return FALSE on the factory method?



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');
}
}


}

Answer



A constructor has to create an instance, i.e. it can't return false or null.



You can stop the instanciation by throwing an exception in your constructor. For example, if you can't make the connection to the database, throw an exception and then catch it in getInstance() to return 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");
}
}


However, I recommend you don't return false in getInstance(), but instead just throw the exception and catch it where the class is used.


No comments:

Post a Comment

c++ - Does curly brackets matter for empty constructor?

Those brackets declare an empty, inline constructor. In that case, with them, the constructor does exist, it merely does nothing more than t...