Using Database Objects with Factory Methods

In this fourth part of a six-part series on implementing factory methods in PHP 5, I show how a simple factory method can improve the efficiency of a sample database-driven application when a database handler is utilized by multiple objects. In this specific case, the method returns Singletons of the database handler, which is a significant enhancement.

As their name clearly suggests, factory methods are regular class methods whose responsibility is to fabricate objects in accordance with the requirements of a specific context. Since these methods are a concrete implementation of the homonymous design pattern, they’re used frequently in mature object-oriented languages like Java and C++. With the introduction of a highly-improved object model, they’ve become very popular in PHP 5 as well.

Since PHP 5 has a much flatter learning curve than Java and C++, defining factory methods with it is a no-brainer process that can be mastered with relative ease, even for developers whom have only an intermediate background in building web applications using the object-oriented paradigm.

So, if you’re a PHP programmer who wants to expand your existing skills and learn how to implement factory methods within your own web-based programs, then this group of articles will hopefully be the guide that you’re looking for.

Logically, if you’ve already read the three tutorials that precede this one, then you should have a solid idea of how to create simple factory methods in PHP 5. In those articles I used a variety of code samples to demonstrate how to define a basic factory class. This class was tasked with returning to client code a couple of objects that represented some common HTML form elements, such as input boxes and text areas.

Besides, this class implemented a static factory method that performed these operations in a pretty straightforward manner, without having to deal with any instances of the class in question. What else can one ask for?

Well, factory methods can be used in all sorts of clever ways, and not only for building a few web form element objects that are not especially interesting. In reality, when developing database-driven applications, one of the most common things a programmer must do is define a factory method that returns a single instance of a database connection handler, which is shared by other objects that need to have access to one or multiple tables.

Given that, in this fourth chapter of the series I’m going to create an scenario similar to the one described above. From this, you’ll learn how to work with factory methods that optimize the way that certain objects interact with a database.

Ready to learn more about this juicy topic? Then start reading right now!

{mospagebreak title=Sharing a database connection handler between different objects}

As I explained in the introduction, my goal here is to show how a factory method can be used for sharing a database connection handler between a couple of objects. With that premise in mind, I’m going to create an example that will do that in a “bad” way, and once you realize why that approach is wrong, I’m going to introduce some improvements to it via the aforementioned factory method.

That being explained, first we need to define a class that abstracts accesses to a database server, which in this particular case will be MySQL. So, here’s the definition of the class that accomplishes this task:

class MySQL

{

private $result = NULL;

private $link = NULL;

 

// 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 nothing difficult to understand with the above “MySQL” class, since it only defines some simple methods that allow you to run queries against a selected database, fetch and count rows in a result set, and find insertion IDs. So far, the way that this class works is pretty understandable, right?

Well, now that we’ve created a basic MySQL abstraction class, suppose for a moment that there’s a another one that needs to use an instance of it to get access to a specified database table. In this typical situation, the class that will use the database handler will be a simple one, called “User,” whose definition will be based partially on the class built by Martin Jansen in his excellent article on Object Overloading in PHP 5.

Having given the corresponding credits, here’s how this brand new class looks:

class User

{

private $data = array();

private $id = NULL;

private $db = NULL;

 

// constructor

public function __construct($id = NULL)

 {

$this->db = new MySQL(‘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 shown above, this brand new “User” class allows you to build objects whose properties persist through different HTTP requests. On one hand, the constructor fetches those properties when applicable, while on the other hand, the destructor is responsible for saving them to a “users” database table.

At this point, I’ve created the scenario mentioned in the introduction: there’s a database handler that is used by another class to access a MySQL table.

So far, all seems to be right with this example, except for one tiny detail. As you may have noticed, the “User” class’s constructor is entirely responsible for creating an instance of the database handler. This is the wrong approach, since in this case each user object must take care only of retrieving and saving its own properties, and not for creating other objects. Period.

This issue can be addressed by implementing the Dependency Injection pattern, but for the moment this topic is out of the scope of this tutorial. So, returning to the previous classes, here’s a script that shows how to use them for building two persistent user objects. Take a look at it:

// 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’;

If you try the above example, you’ll see that it works very well; the information about Susan and Mary will be neatly stored in the “users” MySQL table. However, due to the reasons given before, this isn’t the correct way to put all these classes to work together. Things will get even worse if multiple user objects need to be spawned, since each of them will create a new instance of the MySQL class. Really ugly, right?

Thus, is it possible to do this any better? Of course it is, and to prove this, in the section to come I’m going to add a factory method inside the “MySQL” class, which will help to reduce the number of database handlers used by the user objects.

To see how this factory method will be defined, click on the link below and keep reading.

{mospagebreak title=Defining a simple factory method}

In the preceding segment, I created a sample scenario where one persistent class took advantage of the functionality given by a MySQL database handler to store and retrieve its properties from a specified table. The instantiation of the database handler was performed inside the constructor of the persistent class, which isn’t very convenient.

Therefore, to address this issue, I’m going to modify the signature of the database handler, which now will expose the following factory method:

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

}

}

As you can see, now the “MySQL” class defines a brand new factory method that returns Singletons of the class in question. In doing so, it’s possible to reduce to one the number of database handlers used by the respective persistent class. You’ll understand this better if you look at the improved definition of this class, which now reads as follows:

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

}

}

}

It’s worth noting how the implementation of a basic factory method improves the interaction between the previous persistent class and its dependency, that is the corresponding database handler.

Nonetheless, the most effective way to see how this interaction has been optimized is by means of an example. In the last section of this article I’m going to create that example for you, so you’ll see how two persistent objects can share the same database handler.

To see how this example will be developed, click on the link below and read the next few lines.

{mospagebreak title=The factory method in action}

Now that you hopefully grasped how the two sample classes defined in the previous segment are capable of interacting with each other, it’s time to set up an example that shows them in action. Therefore, I suggest you look at the following script. It demonstrates how to create two persistent user objects that share the same database handler, thanks to the functionality of the factory method. Here it is:  

// 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’;

Even though this code fragment looks similar to the one shown in the first section of this tutorial, the truth is that things are quite different behind the scenes. In that first case, each user object created a different instance of the database handler, while in this last example, only one instance of it is shared between those objects.

While this code sample is rather trivial in its nature, it demonstrates how the definition of a factory method that returns Singletons may help to implement a more effective relationship between some objects and the respective dependencies.

Finally, if you wish to tweak all of the examples included in this article, either for educational purposes or just for fun, feel free to do that. The experience will be instructive, trust me.

Final thoughts

In this fourth installment of the series, I showed how a simple factory method can improve the efficiency of a sample database-driven application when a database handler is utilized by multiple objects. In this specific case, the method in question returned Singletons of the database handler, which is a significant enhancement.

Nevertheless, this example application in its current version is far from being really efficient. The constructor of the previous “User” class is still responsible for creating an instance of the database handler, which you know is a bad thing. Thus, in the next tutorial I’m going to decouple this process, so the involved classes will be able to work more independently.

Don’t miss the upcoming article!

[gp-comments width="770" linklove="off" ]
antalya escort bayan antalya escort bayan