Using the Clone Magic Function in PHP 5

If you’re an eager PHP developer who wants to have at your disposal a quick guide that shows you how to work with the most relevant magic functions provided by PHP 5, then this series of articles might be what you’re looking for. In this fifth part of a seven-part tutorial on magic functions, we’ll briefly review the sleep and wakeup functions, and then tackle the clone function.

Undoubtedly, the release of PHP 5 quite some time ago brought with it a significant advance in the way that web applications are developed nowadays. This is despite the high level of backward compatibility it maintains with its venerable predecessor, PHP 4.

Certainly it’s not breaking news that PHP 5 comes packaged with a robust object model and a whole new set of functions and time-saving libraries, not to mention its handy exception mechanism, which allows it to handle errors and exceptional events in a truly efficient and elegant way.

Of course, when I use the term “functions,” I’m not talking about only the common ones that perform specific tasks such as reading data from a file or applying a filter to a supplied variable. I’m also referring to the magic ones; that is, the functions that have no a concrete implementation by default and are called automatically by the PHP engine in response to certain events.

The trio comprised of the “__set()”, “__get()” and “__call()” methods offer a classic example of magic functions that are used when developing object-oriented PHP applications, but there are a few others that certainly deserve deeper analysis as well.

And speaking of magic functions, you’ll surely recall that I left off the last article discussing the use of the “__sleep()” and “__wakeup()” methods, which are invoked by the PHP interpreter when serializing and unserializing a specified object.

Though these methods were only responsible for echoing to the screen some basic messages when called, the examples developed in the aforementioned tutorial should give you a clear idea of how to use them in a more helpful manner.

Though, as I said before, there are other magic functions that are worth exploring in detail as well. So, with that goal in mind, in this fifth part of the series I’m going to take a closer look at the “__clone()” method, which as its name suggests, is called behind the scenes when using the “clone” PHP keyword.

So, now it’s time to leave the theory behind us and start learning now to use this brand new magic function. Let’s get started right away!

{mospagebreak title=Review: the sleep and wakeup magic functions}

Before I get my hands dirty explaining how to work with the “__clone()” magic function when cloning objects, I’d like to recreate the example shown in the previous article. It demonstrated how to use the  “__sleep()” and “__wakeup()” methods within a basic class called “User.”

Having said that, please look at the full source code of the class in question, which originally was defined like this:

class User

{

// constructor (not implemented)

public function _construct(){}

 

// set undeclared property in a restrictive way

public function __set($property, $value)

{

if (in_array($property, array(‘fname’, ‘lname’, ‘email’)) === TRUE)

{

$this->$property = $value;

}

}

 

// get undeclared property

public function __get($property)

{

if (isset($this->$property))

{

return $this->$property;

}

}

 

// single point to fetch user data

public function __call($method, $args)

{

if ($method === ‘fetch’ AND empty($args) === FALSE)

{

return $this->$args[0];

}

}

 

// implement __sleep() method

public function __sleep()

{

echo ‘Serializing user object’;

return array(‘fname’);

}

 

// implement __wakeup() method

public function __wakeup()

{

echo ‘Unserializing user object’;

}

}

As depicted above, the “User” class gives a simple implementation to both the “__sleep()” and “__wakeup()” magic methods, which in this particular case are only responsible for displaying a rather silly message on the browser.

Nevertheless, the most interesting things happen when an instance of the class that you saw before is serialized and unserialized alternately. This process is clearly illustrated by the example below:

// example on using the ‘User’ class with the ‘__sleep()’ and ‘__wakeup()’ methods

 

$user = new User();

$user->fname = ‘Alejandro’;

$user->lname = ‘Gervasio’;

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

// display user data

echo ‘First Name : ‘ . $user->fetch(‘fname’) . ‘ Last Name : ‘ . $user->fetch(‘lname’) . ‘ Email : ‘ . $user->fetch(‘email’);

/*

displays the following

First Name : Alejandro Last Name : Gervasio Email : alejandro@mydomain.com

*/

 

// serialize user object

$user = serialize($user);

/*

displays the following

Serializing user object

*/

 

// unserialize user object

var_dump(unserialize($user));

/*

displays the following

object(User)[1]

public ‘fname’ => string ‘Alejandro’ (length=9)

*/

As you can see, not only is it possible to use a non-existent “fetch()” method to retrieve the values assigned to the properties of a user object, but this process is complemented with the proper calls to the “__sleep()” and “__wakeup()” functions when the object in question is serialized and unserialized alternately.

Assuming that you’ve grasped the logic that drives the example above, it’s time to explore other magic functions bundled with PHP 5. Therefore, in accordance with the concepts deployed in the introduction of this article, in the next section I’m going to discuss how to use the “__clone()” method. As you might have guessed, it is called by the PHP interpreter when cloning an object via the corresponding “clone” keyword.

To learn more about this interesting topic, click on the link below and read the next few lines.

{mospagebreak title=Triggering functions in the background when cloning objects}

As I explained at the beginning of this tutorial, PHP 5 also includes a magic method called ”__clone(),” which is invoked automatically when using the “clone” keyword. For the sake of brevity, for now I’m going to say only that the “clone” keyword is used to create an independent copy of a specified object, instead of creating a reference to it.

Now, returning to the “__clone()” magic method, it’s possible to give it a concrete implementation, in a way similar to the process performed with other magic functions discussed previously. To accomplish this, I’m going to reuse the “User” class that you saw in the previous section, which now will have the following definition:

class User

{

// constructor (not implemented)

public function _construct(){}

 

// set undeclared property in a restrictive way

public function __set($property, $value)

{

if (in_array($property, array(‘fname’, ‘lname’, ‘email’)) === TRUE)

{

$this->$property = $value;

}

}

 

// get undeclared property

public function __get($property)

{

if (isset($this->$property))

{

return $this->$property;

}

}

 

// single point to fetch user data

public function __call($method, $args)

{

if ($method === ‘fetch’ AND empty($args) === FALSE)

{

return $this->$args[0];

}

}

 

// implement __clone( method

public function __clone()

{

echo ‘Cloning user object.’;

}

}

In this particular case, I decided to give a trivial implementation to the above “__clone()” method to make it simpler for you to grasp, but naturally it can be set up to perform more complex tasks.

However, despite how simple the “__clone()” method may look at first glance, it will be useful to demonstrate how it can be called by the PHP engine automatically when cloning an instance of the sample “User” class.

If you wish to learn the full details of this process, though, you’ll have to read the last section of this tutorial.

{mospagebreak title=Calling the clone method when cloning an object}

The best way to understand how the “__clone()” method is called by the PHP interpreter is by means of a concrete example that shows how to clone an instance of the sample “User” class.

I developed a small script which uses the “clone” keyword to clone an user object, in this way triggering a call to the pertinent “__clone()” method. The definition of this example script is as follows:

$user = new User();

$user->fname = ‘Alejandro’;

$user->lname = ‘Gervasio’;

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

// display user data

echo ‘First Name : ‘ . $user->fetch(‘fname’) . ‘ Last Name : ‘ . $user->fetch(‘lname’) . ‘ Email : ‘ . $user->fetch(‘email’);

/*

displays the following

First Name : Alejandro Last Name : Gervasio Email : alejandro@mydomain.com

*/

 

// clone user object

$newuser = clone $user;

/*

displays the following

Cloning user object.

*/

Simple to code and read, right? As you can see, once the script spawns an object from the “User” class and creates some undeclared properties, it clones this object. This process automatically calls the pertinent “__clone()” method.

As with other magic functions reviewed before, this specific method supports a more complex and useful implementation. So, if the magic functions bundled with PHP 5 have already caught your attention, you might want to sharpen your programming skills by playing with this method a bit when cloning objects. The experience will be really instructive, trust me.

Final thoughts 

Over this fifth chapter of the series, I discussed how to implement and use the “__clone()” magic method, which as you saw earlier, is invoked automatically when an object is cloned via the “clone” keyword.

In the penultimate installment of the series, I’m going to explore in depth another helpful magic method provided by PHP 5, probably one that you’ve used many times before when creating your classes.

In this specific case, I’m talking about the handy “__destruct()” method, which is called by the PHP interpreter before an object gets destroyed at the end of a script.

Want to learn how to use this method? Then don’t miss the next tutorial!

Google+ Comments

Google+ Comments