Before I start building the database-driven application mentioned in the introduction, which will combine the functionality of interfaces and dependency injection to support the use of MySQL and SQLite drivers, first I will review the example developed in the previous installment of the series. In that article, I went through the development of a basic MVC-based program that used dependency injection via a setter method to perform CRUD operations against a predefined MySQL table. Given that, first here is the definition of the class that abstracts the access to MySQL: 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); } } Without a doubt, at this point the definition of the previous “MySQL” class should be very familiar to you, so I’m not going to waste your time (and mine) discussing how it works. Instead, it’s time to show the signature of the model class that comprises this example program, which takes advantage of dependency injection via a setter method to query a “users” MySQL table in a quite abstract manner. Here’s how this model class was built previously: class UserModel { private $db = NULL;
// constructor (not implemented) public function __construct(){}
// setter for database handler public function setDatabaseHandler(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"); } } } As I explained before, in this particular case the above model class simply takes an instance of “MySQL” by means of its “setDatabaseHandler()” method, which permits it to execute CRUD operations against a MySQL table. And speaking of running CRUD operations, below is a script that demonstrates how to do that in a few simple steps: // create new instance of MySQL class $db = new MySQL('host', 'user', 'password', 'database'); $userModel = new UserModel(); // inject MySQL instance in the model via its setter method $userModel->setDatabaseHandler($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); That was really easy to achieve, wasn’t it? As this script shows, it’s amazingly simple to insert, update and delete user-related records, thanks to the intuitive API provided by the model class. However, the nitty-gritty of this example is unquestionably the clever use of dependency injection by means of the “setDatabaseHandler()” method, which expects to passively receive an instance of “MySQL” from the outside. Now that you hopefully recalled how the previous PHP 5-driven application functions, it’s time to continue exploring other scenarios where the dependency injection pattern can be applied successfully. So, in consonance with the concepts deployed in the introduction, in the next segment I’m going to start building a brand new program. It will be able to work equally well with MySQL and SQLite, thanks to the combined use of dependency injection and interfaces. Want to see how the skeleton of this program will be sketched out? Then click on the link below and keep reading.
blog comments powered by Disqus |
|
|
|
|
|
|
|