Since the MySQL driver that you saw earlier can only create a Singleton instance of itself, and establish a connection to the server, below I listed the finished version of it. It includes some extra methods that allow it to run SQL statements, retrieve insertion IDs and close the connection. Here's how the enhanced version of the driver now looks: class MySQLiWrapper extends MySQLi {
private static $_instance = NULL; private $_config = array();
// 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(){}
// establish a connection to MySQL public function connect() { list($host, $user, $password, $database) = $this->_config; parent::__construct($host, $user, $password, $database); if ($this->connect_error) { throw new Exception('Error connecting to MySQL : ' . $this->connect_errno . ' ' . $this->connect_error); } unset($host, $password, $database); } // perform query public function runQuery($query) { if (is_string($query) AND !empty($query)) { // lazy connect to MySQL $this->connect(); // run the specified query if ((!$this->real_query($query))) { throw new Exception('Error performing query ' . $query . ' - Error message : ' . $this->error); } return new MySQLi_ResultWrapper($this); } }
// get insertion ID public function getInsertID() { return $this->insert_id; }
// close database connection public function __destruct() { $this->close(); } } Not too bad, considering that this class is only an introductory example, eh? As you can see, now the driver implements a whole new method called "query()" for running hard-coded SQL queries. This method is somewhat special, as it composes a whole new object named "MySQLi_ResultWrapper." Quite possibly you're wondering what the point is in spawning another object. Well, as you'll see in the forthcoming tutorial, this object's originating class will be used to manipulate result sets in a separate way, which helps to keep the code that connects to MySQL and runs queries isolated from the one that processes data sets. But for the moment, I suggest you stay focused on the definition of the MySQL driver. It recreates a real-world case where a static property can be really useful for implementing the Singleton design pattern in a painless manner. Final thoughtsIn this introductory chapter of the series, I showed you how the declaration and further use of a single static property inside a MySQL abstraction class can be useful for turning this class into a Singleton. While it's fair to say that there are different approaches that can be utilized for implementing this design pattern, most of them will employ a static variable. Before I forget to mention it, you should notice that the "query()" method of the previous MySQLi wrapper creates an instance of a result set object. Naturally, the originating class of this object has not been defined yet, but this process will be covered in the course of the subsequent tutorial. To learn more on this topic, don't miss the next part!
blog comments powered by Disqus |
|
|
|
|
|
|
|