Home arrow PHP arrow Page 2 - Applying the Dependency Injection Pattern and Factory Methods in PHP 5

Review: the classes so far - PHP

Welcome to the final part of a series on implementing factory methods in PHP 5. Composed of six approachable tutorials, this series uses numerous hands-on examples to teach you how to define specific methods within your own PHP programs. These methods return to client code instances from their originating classes, and from other classes as well.

TABLE OF CONTENTS:
  1. Applying the Dependency Injection Pattern and Factory Methods in PHP 5
  2. Review: the classes so far
  3. Removing the factory method from the MySQL class
  4. Creating persistent objects without a factory method
By: Alejandro Gervasio
Rating: starstarstarstarstar / 1
December 15, 2009

print this article
SEARCH DEV SHED

TOOLS YOU CAN USE

advertisement

Before I start explaining how to apply the Dependency Injection pattern to the example application developed in the previous installment, let's review how the classes that composed this small program were defined originally.

So, here is the signature corresponding to the class that abstracts accesses 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);

}

}

At this point, the definition of the above MySQL abstraction class should be pretty familiar to you, so I’m not going to waste your time explaining how it works. Instead, let me show you the signature of the other sample class, which takes advantage of the functionality given by the previous one to persist through multiple HTTP requests.

Here’s how this persistent class looks:

class User

{

private $data = array();

private $id = NULL;

private $db = NULL;

 

// constructor

public function __construct(MySQL $db, $id = NULL)

{

$this->db = $db;

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");

}

}

}

Definitively, what I said about the previous MySQL abstraction class is also valid for the one above, since at this point you’ll be familiar with the logic driving this persistent class. It’s fair to note an important detail, though, about the way that this class uses the functionality of “MySQL.” As you can see, an instance of this database handler is directly passed to the constructor of the class, an approach commonly known in software development as “dependency injection by constructor.” Expressed in other words, it's a simple implementation of the Dependency Injection pattern.

Well, having roughly outlined the logic that drives the previous “MySQL” and “User” classes, below I coded a couple of scripts that show them in action.

The first of these scripts uses the factory method of the database handler in a rather inefficient manner to create two persistent objects:

// create first user object

$user1 = new User(MySQL::factory('host', 'user', 'password', 'database'));

$user1->name = 'Susan Norton';

$user1->email = 'susan@domain.com';

 

// create second user object

$user2 = new User(MySQL::factory('host', 'user', 'password', 'database'));

$user2->name = 'Mary Smith';

$user2->email = 'mary@domain.com';

That was easy to grasp, right? Now, take a look at the following fragment, which utilizes the factory method of the database handler in a slightly more clever way:

// create instance of MySQL class via the factory method

$db = MySQL::factory('host', 'user', 'password', 'database');

// create first user object

$user1 = new User($db);

$user1->name = 'Susan Norton';

$user1->email = 'susan@domain.com';

 

// create second user object

$user2 = new User($db);

$user2->name = 'Mary Smith';

$user2->email = 'mary@domain.com';

Without a doubt, understanding how these two scripts work should be a straightforward process for you. All they do is show how useful a factory method can be for efficiently controlling the creation of objects.

However, this example is pretty particular, since the application of the Dependency Injection pattern permits you to easily get rid of the previous factory method. Don’t believe that this may be that easy? Well, to prove it, in the following section the method will be removed from the MySQL abstraction class, without producing any impact in the creation of persistent objects.

To see how this will be done, read the next segment.



 
 
>>> More PHP Articles          >>> More By Alejandro Gervasio
 

blog comments powered by Disqus
escort Bursa Bursa escort Antalya eskort
   

PHP ARTICLES

- Hackers Compromise PHP Sites to Launch Attac...
- Red Hat, Zend Form OpenShift PaaS Alliance
- PHP IDE News
- BCD, Zend Extend PHP Partnership
- PHP FAQ Highlight
- PHP Creator Didn't Set Out to Create a Langu...
- PHP Trends Revealed in Zend Study
- PHP: Best Methods for Running Scheduled Jobs
- PHP Array Functions: array_change_key_case
- PHP array_combine Function
- PHP array_chunk Function
- PHP Closures as View Helpers: Lazy-Loading F...
- Using PHP Closures as View Helpers
- PHP File and Operating System Program Execut...
- PHP: Effects of Wrapping Code in Class Const...

Developer Shed Affiliates

 


Dev Shed Tutorial Topics: