In the previous article of this series I discussed how to apply the dependency injection pattern via a constructor method, which was coded inside a model class. Below I reintroduced the complete definitions of the classes that comprised this example, starting with the source code corresponding to the MySQL database handler mentioned at the beginning. Here’s how this particular class was defined originally: 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); } } Certainly, there’s not much to be said about the logic driving the previous “MySQL” class, since all that it does is build a simple abstraction layer that allows you to perform common operations against a selected MySQL database through a simple API. Period. While analyzing the internals of the database handling class may be pretty boring for you, things will definitely become much more interesting when you look at the definition of the model below. It uses the functionality of “MySQL” for accessing a predefined “users” table. See for yourself how this process is accomplished: class UserModel { private $db = NULL;
// constructor public function __construct(MySQL $db) { $this->db = $db; }
// get all users public function getAll() { return $this->db->query("SELECT * FROM users"); }
// get a single user public function get($id = 1) { return $this->db->query("SELECT * FROM users WHERE id = '$id'"); }
// create/update user public function save($data, $id = NULL) { if (is_array($data) && !empty($data)) { if ($id === NULL) { $data = array_values($data); $fields = ''' . implode("','", $data) . '''; $this->db->query("INSERT INTO users (id, fname, lname, email) VALUES (NULL, $fields)"); } else { $fields = ''; foreach ($data as $field => $value) { $fields .= $field . '='' . $value . '','; } $fields = substr($fields, 0, -1); $this->db->query("UPDATE users SET $fields WHERE id=$id"); } } }
// delete user public function delete($id = NULL) { if ($id !== NULL) { $this->db->query("DELETE FROM users WHERE id=$id"); } } } Not too bad, huh? As shown before, the “UserModel” accepts an instance of the MySQL class, which is finally stored as a property, so it can be accessed by all of the model’s methods. Undeniably, the beauty of this approach is that it shows in a nutshell how a proper implementation of dependency injection can reveal the power of the Inversion of Control principle. This principle states that the context of an object is responsible for providing it with its dependencies, and not the inverse process. So far, so good. Now that you've relearned how the two previous classes interact with each other, here’s a basic script that demonstrates how to use them for running some CRUD operations against the “users” MySQL table. Take a look at it: // create new instance of MySQL class $db = new MySQL('host', 'user', 'password', 'database'); // inject instance of MySQL in the model via its constructor $userModel = new UserModel($db); // add new user $userModel->save(array('fname' => 'Alejandro', 'lname' => 'Gervasio', 'email' => 'alejandro@domain.com')); // update existing user $userModel->save(array('fname' => 'Mary', 'lname' => 'Wilson', 'email' => 'mary@domain.com'), 1); // delete existing user $userModel->delete(1); Easy to code and read, isn’t it? As this code fragment shows, it’s very simple to combine the functionality of the MVC pattern and dependency injection to build a program that handles user-related database records. However, as you can see above, the dependency, which in this case happens to be an instance of the “MySQL” class, is inputted into the model via its constructor. What if I show you how to achieve the same result by using a setter method instead? Assuming that you’re interested in learning how to accomplish this, in the following section I’m going to add the setter to the model class, thus implementing another handy variation of the dependency injection pattern. Now, click on the link below and read the following segment, please.
blog comments powered by Disqus |
|
|
|
|
|
|
|