In the introduction, I said that a simple factory method can improve the relationship established between a persistent class and its corresponding dependency, which in this case happens to be a MySQL database handler. However, it’d be quite useful to recall how these sample classes were defined in the preceding tutorial, and how they can be put to work together as well. Bearing this in mind, below I listed the signatures of those classes, accompanied by a short script that shows how to use them in a concrete situation. First, take a look at the definition of the MySQL handling class: class MySQL { private $result = NULL; private $link = NULL; private static $instance = NULL;
// returns a singleton instance of MySQL class (chainable) public static function factory($host, $user, $password, $database) { if (self::$instance === NULL) { self::$instance = new MySQL($host, $user, $password, $database); } return self::$instance; } // connect to MySQL public function __construct($host, $user, $password, $database) { if (FALSE === ($this->link = mysqli_connect($host, $user, $password, $database))) { throw new Exception('Error : ' . mysqli_connect_error()); } }
// perform query public function query($query) { if (is_string($query) AND empty($query) === FALSE) { if (FALSE === ($this->result = mysqli_query($this->link, $query))) { throw new Exception('Error performing query ' . $query . ' Error message :' .mysqli_error($this->link)); } } }
// fetch row from result set public function fetch() { if (FALSE === ($row = mysqli_fetch_assoc($this->result))) { mysqli_free_result($this->result); return FALSE; } return $row; }
// get insertion ID public function getInsertID() { return mysqli_insert_id($this->link); } // count rows in result set public function countRows() { if ($this->result !== NULL) { return mysqli_num_rows($this->result); } } // implement destructor to close the database connection function __destruct() { mysqli_close($this->link); } } And now that you've surely recalled how the “MySQL” class looked, here’s the other one, which takes advantage of the functionality of “MySQL” to save and retrieve its properties from a specified database table: class User { private $data = array(); private $id = NULL; private $db = NULL;
// constructor public function __construct($id = NULL) { $this->db = MySQL::factory('host', 'user', 'password', 'database'); if ($id !== NULL) { $this->id = $id; $this->db->query('SELECT * FROM users WHERE id=' . $this->id); $this->data = $this->db->fetch(); } }
// set undeclared property public function __set($property, $value) { if ($property !== 'name' and $property !== 'email') { return; } $this->data[$property] = $value; }
// get undeclared property public function __get($property) { if (isset($this->data[$property]) === TRUE) { return $this->data[$property]; } }
// save object to session variable public function __destruct() { if ($this->id === NULL) { $this->db->query("INSERT INTO users (id, name, email) VALUES (NULL, '$this->name', '$this->email')"); } else { $this->db->query("UPDATE users SET name = '$this->name', email = '$this->email' WHERE id = $this->id"); } } } As I explained before, this “User” class is a blueprint for building persistent objects that use a MySQL table to store the values assigned to its pertinent properties. However, the most relevant detail concerning the way this class works is the implementation of its constructor, since this method is entirely responsible for building an instance of the database handler. Even though the factory method of the database handler returns only Singletons to client code, this obviously isn’t a good thing. The persistent class should only be tasked with handling its properties, not with spawning other objects. In addition, here’s a basic example that shows how to make use of the two classes shown previously for creating two persistent user objects: // create first user object $user1 = new User(); $user1->name = 'Susan Norton'; $user1->email = 'susan@domain.com';
// create second user object $user2 = new User(); $user2->name = 'Mary Smith'; $user2->email = 'mary@domain.com'; Well, to be frank, the above script looks pretty clean, and works well enough, since the persistent objects are constructed in a straightforward fashion. Nonetheless, things are a bit more complicated behind the scenes due to the incorrect instantiation of the database handler. So, can this issue be addressed easily? Fortunately, the answer is a resounding yes! A small change in the definition of the constructor of the persistent “User” class will solve this problem. But the full details of this modification will be discussed in the next section. So, go ahead and read the following segment.
blog comments powered by Disqus |
|
|
|
|
|
|
|