Saving Class Instances to Files with Persistent Objects

Welcome to the third part of a six-part series on building persistent objects in PHP 5. Through a decent variety of code samples, this series provides you with the right pointers to start creating objects that can save themselves to a persistent storage mechanism, including simple cookies, plain text files, and MySQL database tables.

Though it may sound scary and a bit intimidating, creating objects in PHP 5 that can maintain their state through a number of HTTP requests is an extremely simple process. It only requires an intermediate background in the object-oriented paradigm, along with a basic understanding of how to serialize/unserialize objects.

So, if you’re a PHP developer who wants to master the key concepts that surround the creation of this kind of object without having to spend endless hours reading the PHP manual, then this group of articles may be the material that you’re looking for.

And now that you’ve been introduced to the main goal of the series, it’s time to review the topics that were covered in the last article. In that tutorial I explained  how to build a basic PHP 5 class which was capable of saving an instance of itself to a specified session variable. This ability allowed it to persist across different web pages.

Also, it’s worth mentioning that this class implemented a static factory method, which allowed it to retrieve class instances in a truly painless way, without our having to explicitly code any constructor.

Though, as I said a few moments ago, a persistent object can also use different mechanisms to maintain its status; that naturally includes text files. Thus, in this third chapter of the series, I’m going to discuss how to build a class that stores instances of itself in a specified file.

Are you ready to learn more on this topic? Start reading right now!

{mospagebreak title=Review: a basic persistent class}

Before I start explaining how to build a class capable of saving its instances to a text file, I’m going to reintroduce the example developed in the preceding tutorial. It demonstrated how to create a similar class, but in that particular case, it used a session variable as its default storage mechanism.

First, here’s the complete source code corresponding to that persistent class, so you can quickly recall how it originally looked:

class User

{

private $data = array();

private static $key = ‘user';

 

// constructor (not implemented)

public function __construct(){}

 

// factory method

public static function factory($key = ”)

{

session_start();

if ($key != ”)

{

self::$key = $key;

}

if(isset($_SESSION[self::$key]) === TRUE)

{

return unserialize($_SESSION[self::$key]);

}

return new User();

}

 

// set undeclared property

public function __set($property, $value)

{

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

{

$_SESSION[self::$key] = serialize($this);

 }

}

As I explained before, the above “User” class can save an instance of itself to a custom session variable, in this case by giving a basic implementation to its destructor. On the other hand, its factory method permits you to load or create a user object, and eventually to assign new values to its properties.

These two well-differentiated processes are shown by the following script:

// example on creating a persistent object

$user = User::factory(‘newuser’);

$user->fname = ‘Alejandro';

$user->lname = ‘Gervasio';

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

I believe that this code fragment should be easy for you to grasp. It first spawns a brand new user object,  and then it creates dynamically some properties along with their corresponding values. Finally, it saves the object to a session variable, which for this occasion happens to be referenced as $_SESSION['newuser'].

Once the previous user object has been stored in the session variable, say that it needs to be retrieved on a different web page for further manipulation. In a case like this, the code snippet below will perform that task in a simple manner:

// assign new values to properties of the persistent object

$user = User::factory(‘newuser’);

$user->fname = ‘Mary';

$user->lname = ‘Smith';

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

What’s more, if incidentally the previous user object is required by another file, then the whole retrieval process would be as simple as loading it via its factory method, as shown below:

$user = User::factory(‘newuser’);

So far, so good. At this point, I’m sure that you already grasped the underlying logic that drives the previous example, meaning that it’s time to explore a few other ways to create persistent objects with PHP 5. So, as I stated in the introduction, it’s possible to build this type of object by using a plain text file as the default storage mechanism instead of working with cookies, which as you know can be disabled in the client.

Provided that you’re interesting in learning how to accomplish this, in the following section I’m going to define a whole new persistent class, which obviously will be capable of saving instances of itself to a specified text file.

To see how this class will be built, click on the link below and keep reading.

{mospagebreak title=Saving class instances to a text file} 

If you found it easy to understand how the previous persistent class worked, then you’ll see that building one that stores its instances in a text file is an even simpler process.

To demonstrate the veracity of my claim, I rebuilt the “User” class, which now will be capable of persisting through different HTTP requests, thanks to its ability for saving its spawned objects to a predefined file called “data.txt.” The new definition of this class is shown below, so take a look at it:

class User

{

private $data = array();

private $file = ‘data.txt';

 

// constructor

public function __construct()

{

list($this->data['name'], $this->data['email']) = explode(‘|’, file_get_contents($this->file));

}

 

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

{

file_put_contents($this->file, $this->name . ‘|’ . $this->email);

}

}

Undeniably, the signature of the above “User” class looks at first sight quite similar to the one shown in the previous segment, with some important differences worth spotting. In this specific case, the class implements its constructor and destructor methods to seamlessly support the creation, loading and storage of its properties to a text file.

Besides, the magic “__set()” and “__get()” methods have been slightly modified to accept creating only a couple of “name” and “email” properties. It’s possible, of course, to code these to be a bit more permissive with reference to the properties that can be created.

Having explained how the brand new “User” class does its thing, it’s time to give it a try and see if it’s really capable of persisting through several web pages, right? Below I coded a script that first spawns a user object, and then assigns some values to its properties; finally, it saves them to the specified “data.txt” file.

Here’s the script that does all that:

// example on using a persistent object with a text file

$user = new User();

$user->name = ‘Alejandro';

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

// __destruct() saves automatically the object to the target file

Definitely, the “User” class does decent work saving the state of its instance to a text file, as you can clearly see from the above code fragment. However, this is only half of the process; it’s also necessary to see how the properties of that particular instance can be retrieved on a different web page.

Showing how to perform that task will be the conclusion of this tutorial. So, to learn the full details of this process, go ahead and read the last section.

{mospagebreak title=Retrieving an object in a different PHP file}

In the previous segment, the properties assigned to an object derived from the sample “User” class were saved to a text file. Having discussed the underlying logic of this process, the only thing that remains undone is showing how those properties can be easily retrieve by a different PHP file.

Taking into account this requirement, below I defined such a file. It performs the retrieval process and assigns new values to the respective properties before storing them again in the target file. Here’s how this file looks:

<?php

 

class User

{

private $data = array();

private $file = ‘data.txt';

 

// constructor

public function __construct()

{

list($this->data['name'], $this->data['email']) = explode(‘|’, file_get_contents($this->file));

}

 

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

{

file_put_contents($this->file, $this->name . ‘|’ . $this->email);

}

}

 

// assign new values to properties of the persistent object

$user = new User();

$user->name = ‘Susan';

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

// __destruct() saves automatically the object to the target file

 

?>

Hopefully, if all has gone well, after running the previous file, the name and email of my friend Susan have been saved to the “data.txt” file. thus preserving these properties for further handling. This example proves how simple it is to create objects that are capable of saving their properties to a predefined text file.

Of course, it’s valid to point out that in this case only the object’s properties are stored, so if an application also needs to preserve the methods, then an approach that uses serialization/unserialization would probably be the best option to pick up.

Finally, feel free to introduce your own enhancements to the example class shown before, so you can sharpen your existing skills in building persistent objects in PHP 5.

Final thoughts

In this third part of the series, you learned how to build a basic PHP 5 class that could store instances of itself to a predefined text file, thus exploring yet another approach to creating persistent objects in a straightforward fashion.

In the upcoming tutorial, I’m going to enhance the existing functionality of this sample class by providing it with the capacity for using different text files as its default storage mechanism.

Here’s my final piece of advice: don’t miss the next part!

[gp-comments width="770" linklove="off" ]

chat