As I promised in the section that you just read, in the lines to come I developed a basic example aimed at demonstrating how to work with the prior MySQL abstraction class. First, I included the full definition of the driver, accompanied by the corresponding code sample. Take a look, please: class MySQL { private $_result = NULL; private $_link = NULL; private $_config = array(); private static $_instance = NULL;
// return Singleton instance of MySQL class public static function getInstance(array $config = array()) { if (self::$_instance === NULL) { self::$_instance = new self($config); } return self::$_instance; }
// private constructor private function __construct(array $config) { if (count($config) < 4) { throw new Exception('Invalid number of connection parameters'); } $this->_config = $config; }
// prevent cloning class instance private function __clone(){}
// connect to MySQL private function connect() { // connect only once static $connected = FALSE; if ($connected === FALSE) { list($host, $user, $password, $database) = $this->_config; if ((!$this->_link = mysqli_connect($host, $user, $password, $database))) { throw new Exception('Error connecting to MySQL : ' . mysqli_connect_error()); } $connected = TRUE; unset($host, $user, $password, $database); } }
// perform query public function query($query) { if (is_string($query) and !empty($query)) { // lazy connect to MySQL $this->connect(); if ((!$this->_result = mysqli_query($this->_link, $query))) { throw new Exception('Error performing query ' . $query . ' Message : ' . mysqli_error($this->_link)); } } }
// fetch row from result set public function fetch() { if ((!$row = mysqli_fetch_object($this->_result))) { mysqli_free_result($this->_result); return FALSE; } return $row; }
// get insertion ID public function getInsertID() { if ($this->_link !== NUlL) { return mysqli_insert_id($this->_link); } return NULL;
}
// count rows in result set public function countRows() { if ($this->_result !== NULL) { return mysqli_num_rows($this->_result); } return 0; }
// close the database connection function __destruct() { is_resource($this->_link) AND mysqli_close($this->_link); } }// End MySQL class
// create instance of MySQL class $db = MySQL::getInstance(array('host', 'user', 'password', 'database')); // fetch users from database table $db->query('SELECT * FROM users'); // display user data while ($user = $db->fetch()) { echo 'First Name: ' . $user->fname . ' Last Name: '. $user->lname . ' Email: '. $user->email . '<br />'; } In the above script, the reason for making the constructor of the MySQL driver private becomes evident, as an instance of the class is only grabbed through its “getInstance()” static method. One this has been done, the corresponding instance is used to fetch some records from a “users” table, and finally the data is echoed to the browser in a standard fashion. If you grasped the underlying logic of the previous example, at this point you have a better idea of how to use a private constructor in a more realistic situation. In this particular case, the method was employed to build a Singleton class, but there are many other situations where restrictive constructors can be quite helpful as well. Final thoughts That’s all for now. In this third installment of the series, I showed you that a private constructor can be truly helpful when it comes to more strictly implementing the Singleton design pattern. In this concrete case, the pattern was applied within a class that behaved like a simple MySQL abstraction layer, but as you may guess the same concept can be extended to other classes as well. In the next tutorial, I’m going to provide you with yet another example regarding the use of a private constructor in PHP 5, which this time will be utilized for building a purely-static HTML form helper class. Here’s my little piece of advice: don’t miss the forthcoming part!
blog comments powered by Disqus |
|
|
|
|
|
|
|