A Persistent Class in Action

If you’re a PHP developer who wants to learn how to create objects that can maintain their state through different HTTP requests, either by using cookies, plain text files or MySQL database tables, then don’t look any further because you’ve come to the right place. Welcome to the last part of a six-part series on building persistent objects in PHP 5. This tutorial series introduces the key concepts that surround the creation of persistent objects, and complements the corresponding theory with copious code samples.

And now that you know what to expect from this set of articles, it’s time to review the topics that were discussed in the last one. In that part of the series I built a simple example class in PHP 5, which was able to save its properties, along with the values assigned to them, to a MySQL table.

All of the database operations required to save the example class’s properties were delegated to an instance of a basic MySQL abstraction class. This abstraction class was injected (or aggregated) into the constructor of the persistent class.

Of course, the best part of defining a class like this is that it’s possible to retrieve its properties at a later time on a different PHP file, thus building a software entity that can persist (at least partially) across a number of web pages.

However, the best way to understand how the two classes referenced above can interact with each other is by means of a concrete example. Therefore, in this last installment of the series I’m going to set up that example for you. Doing so will wrap up this introductory guide to building persistent objects in PHP 5.

Ready to tackle the final chapter of this hopefully instructive journey? Then, let’s get started right now!

{mospagebreak title=Review: creating a database-driven persistent class}

To understand how the pair of sample classes mentioned in the introduction can be put to work in tandem to create a persistent object whose properties will be saved to a MySQL table, it’d be useful to recall how these classes were initially defined in the preceding tutorial.

Here’s the source code that corresponds to the MySQL abstraction class. It’s responsible for performing queries against a selected database. Take a look at its short definition:

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

{

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

}

}

Since in the previous installment I covered in detail how the above “MySQL” class works, I’m not going to bore you with redundant explanations of the way that each of its methods have been implemented. The only thing worth noting here is that the class packages enough functionality for connecting to MySQL and running queries, counting the number of rows in a result set, and so forth.

Now it’s time to show the definition of the persistent class, which I called “User,” since it stores user-related data on a specified MySQL table.

The complete signature of this sample class is as follows:

class User

{

private $data = array();

private $id = 1;

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 class properties to MySQL table

public function __destruct()

{

$this->db->query("UPDATE users SET name = ‘$this->name’, email = ‘$this->email’ WHERE id = $this->id");

}

}

Even though the definition of the previous “User” class looks pretty skinny and compact, it performs a few interesting tasks that are worth a closer look. As you can see, aside from implementing the “__set()” and “__get()” PHP 5 magic methods, which permit it to handle undeclared properties on the fly, the class also uses its constructor to retrieve those properties from a fictional “users” MySQL table.

Next, these properties are stored in the internal $data array, which lets the destructor save them again to the “users” table, right before the PHP interpreter finishes executing the calling script.

The question that comes up at this point is: do you have a vague idea of how to create a persistent object with the two classes shown earlier? I’m sure you do! Nonetheless, to dissipate any doubts that you may have on this subject, in the course of the following section I’m going to create a brand new example that will put these classes together so you can see them in action. 

To learn how this particular example will be developed, please click on the link that appears below and keep reading.

{mospagebreak title=Spawning a persistent object from the User class}

In the previous segment, I explained briefly how the “MySQL” and “User” classes do their respective businesses, but always theoretically. Now, it’s time to see how they can be used for creating an object capable of maintaining the values assigned to its properties through different HTTP requests.

Below I coded a simple script that first spawns an object from the originating “User” class, along with a couple of properties, and then saves those properties to the sample “users” MySQL table, thanks to the functionality provided by the corresponding MySQL abstraction class.

The source code of the script is as follows:

// example on using a persistent object

// connect to MySQL

$db = new MySQL(‘host’, ‘user’, ‘password’, ‘database’);

$user = new User($db);

// create user properties and assign values to them

$user->name = ‘Alejandro’;

$user->email = ‘alejandro@mydomain.com’;

// __destruct() saves automatically object’s properties to the database

See how simple it is to create a database-driven persistent object in PHP 5? The above code sample should answer this question for itself. As I explained earlier, once an instance of the “MySQL” class has been injected into the constructor of “User,” the “name” and “email” properties created dynamically are stored automatically on the “users” MySQL table, thanks to the clever implementation of the destructor.

Of course, it’s valid to point out here that all of these operations could be performed using a group of regular methods, instead of the magic ones available in PHP 5. For instance, instead of implementing a destructor to save the properties of an object, a regular “save()” method could be used to produce the same result.

However, since my purpose here was demonstrating how to create a persistent object with a minimal amount of code, I decided to use the magic methods that you saw before.

Having clarified that point, and now that the properties of the previous $user object have been stored in the corresponding MySQL table, the only step that remains is to show you how the properties in question can be restored on a different web page.

This process will be discussed in detail in the last section of this tutorial. Thus, to get there simply click on the link below and keep reading.

{mospagebreak title=Retrieving properties of a persistent object on a different web page}

As I said in the section that you just read, the only thing left to explain here is how the properties of the user object created previously can be restored by a different PHP file. So, assuming that the definitions of the classes defined earlier have been included in this file, it would look similar to this:

$db = new MySQL(‘host’, ‘user’, ‘password’, ‘database’);

$user = new User($db);

// display values of properties

echo $user->name;

echo $user->email;

That was simple to accomplish, wasn’t it? But I’d like to take this example even further. Say that it’s necessary to assign new values to the “name” and “email” properties of the user object. Well, this process would be performed in the following way:

$db = new MySQL(‘host’, ‘user’, ‘password’, ‘database’);

$user = new User($db);

// create user properties and assign values to them

$user->name = ‘Mary’;

$user->email = ‘mary@mydomain.com’;

// __destruct() saves automatically object’s properties to the database

There you have it. Finally, I managed to build a basic class whose persistent storage mechanism is a simple MySQL table. Also, in this particular example only the properties of an instance of that class are saved to the target table, so if an application needs to save the whole instance, it’d be necessary to implement some methods that serialize/unserialize the object alternately.

But, guess what? This will be left as homework for you. So get your hands dirty and get started building your own persistent objects. The experience will be really educational, trust me!

Final thoughts

We’ve finally come to the end of this series. But hopefully the whole experience has been instructive and also fun, since you learned a few different approaches to building persistent objects in PHP 5. Ranging from using cookies and plain text files to utilizing MySQL tables as the storage mechanisms associated with a particular class, creating this type of object is indeed a no-brainer process that you’ll surely master in a very short time.

See you in the next PHP development tutorial!

Google+ Comments

Google+ Comments