Executing Destructors Manually in PHP 5

Welcome to the final chapter of the series “Understanding Destructors in PHP 5.” In consonance with this article’s title, this series walks you through the basics of utilizing class destructors in object-based applications and also provides you with a decent number of hands-on examples, so you can start incorporating these useful methods into your PHP 5 classes with minor efforts.

If you’re a PHP developer who has spent a considerable amount of time using the set of brand new features incorporated into the object model of PHP 5, then there’s the possibility that you’ve already worked with class destructors. However, you may want to refresh their foundations or simply fill some gaps regarding their adequate implementation, so don’t hesitate to start reading this article series now!

Now that you hopefully have a clear idea on the purpose of this article series, it’s an appropriate moment to make a brief recapitulation about the items that were discussed in great detail during the previous tutorial of the series. As you’ll surely recall, in that particular installment I demonstrated how to retrieve useful information about a few user handling objects, such as their respective properties and methods, prior to being removed by the PHP engine.

This process was performed successfully by way of a single destructor method whose implementation consisted first of iterating over the properties and methods of a particular object, and then displaying this data on the browser. By using this simple, yet effective, approach it was possible to build a mechanism that printed structural information on a specific object onto the screen right before being destroyed by the PHP interpreter.

All right, at this point I should assume that implementing destructors in a useful way is now a familiar concept to you, which may lead you to erroneously think that the topic doesn’t bear further discussion. Well, not so fast, since there’s an important point that still remains uncovered and here it comes:

As you learned so far, destructors were called automatically by the PHP engine before finishing the execution of a determined script. However, did you ever think that these methods could be forced to run manually? Yes, you’re correct! If you purposely delete an object that implements a destructor, logically it will be called without the need to abruptly terminate the execution of a given script. Sounds quite interesting, right?

Therefore, in this final tutorial of the series I’m going to show you how to manually trigger a destructor, and in addition you’ll learn how to emulate the behavior of this magic method when using PHP 4.

Are you ready to tackle this last chapter of this educational journey? Let’s get started!

{mospagebreak title=Triggering a destructor manually}

As I said in the beginning, it’s perfectly possible to call the destructor of a determined object without having to end the execution of an application or script. Since in all the cases a destructor will be invoked when its pertinent object no longer exists, this process can be triggered manually simply by removing the  object via the “unset()” PHP native function.

As you’ll possibly know, this function comes in handy for removing unwanted variables of all types, and these also include objects. The concept is theoretically interesting, therefore I’m going to demonstrate how to manually call a destructor by using the same “User” class that you saw in previous articles of the series.

Its respective definition was the following:


// define ‘User’ class

class User{

private $firstName;

private $lastName;

private $email;

public function __construct($firstName,$lastName,$email){

if(!$firstName||strlen($firstName)>32){

throw new Exception(‘Invalid First Name parameter!’);

}

if(!$lastName||strlen($lastName)>32){

throw new Exception(‘Invalid Last Name parameter!’);

}

if(!$email||!preg_match("/^.+@.+..+$/",$email)){

throw new Exception(‘Invalid Email parameter!’);

}

$this->firstName=$firstName;

$this->lastName=$lastName;

$this->email=$email;

}

// get user’s first name

public function getFirstName(){

return $this->firstName;

}

// get user’s last name

public function getLastName(){

return $this->lastName;

}

// get user’s email

public function getEmail(){

return $this->email;

}

// get all user data

public function getAll(){

return ‘First Name: ‘.$this->firstName.’ Last Name: ‘.$this->lastName.’ Email Address: ‘.$this->email;

}

// implement a __destruct()’ method

public function __destruct(){

// display object properties

echo ‘<h2>Properties of object being destroyed</h2>';

foreach(get_object_vars($this) as $prop=>$val) {

 echo ‘<p>’.$prop.’=’.$val.'</p>';

 }

// display object methods

echo ‘<h2>Methods of object being destroyed</h2>';

$methods=get_class_methods(get_class($this));

foreach($methods as $method) {

echo ‘<p> Method Name: ‘.$method.'()</p>';

}

}

}


Now that you hopefully recalled how the above class does its business, let me show you a concrete example where its respective constructor is called manually using the popular “unset()” PHP function.

Having said that, here’s how this brand new example looks:


try{

// create user

$user=new User(‘John’,’Doe’,’john@domain.com’);

// display separately user data

echo ‘First Name: ‘.$user->getFirstName().'<br />';

// delete object, so this triggers its ‘__destruct()’ method

unset($user);

echo ‘Last Name: ‘.$user->getLastName().'<br />';

echo ‘Email: ‘.$user1->getEmail().'<br />';

// display all user information

echo ‘Complete user information: ‘.$user1->getAll();

 

/* displays the following:

 

First Name: John

 

Properties of object being destroyed

 

firstName=John

lastName=Doe

email=john@domain.com

 

Methods of object being destroyed

 

Method Name: __construct()

Method Name: getFirstName()

Method Name: getLastName()

Method Name: getEmail()

Method Name: getAll()

Method Name: __destruct()


Fatal error: Call to a member function getLastName() on a non-object in path/to/example

 

*/

}

catch(Exception $e){

echo $e->getMessage();

exit();

}


After studying the previous example, you’ll have to admit that things suddenly become exciting! As you can see, once a generic user handing object is created by the above script, the object in question is deliberately deleted by way of the aforementioned “unset()” PHP function.

This trick results in the immediate execution of its destructor, certainly a process shown clearly by the output generated by the prior script. Now, at this point, do  you see how easy it is to make a destructor run without waiting for a script to finish? I guess you do!

However, the example that you just learned uses only one object along with its corresponding destructor. But what about using multiple objects and destructors that are called manually? Indeed, it sounds like something promising and useful. Thus in the next section, I’m going to show you precisely how to fire up different destructors by using the “unset()” PHP function utilized previously.

To learn the details of how this process will be achieved, please click on the link below and keep reading.

{mospagebreak title=Calling multiple destructors manually}

During the prior section, you learned how to manually trigger the destructor of a trivial user handling object without having to abruptly stop the execution of a script. As you may have guessed, this approach can be easily extended to work with multiple objects and destructors.

Basically the logic behind this idea remains the same: once these objects are spawned, they’re purposely deleted via the pertinent “unset()” PHP function, as I did earlier.

Having explained how to execute different destructors manually, I’m going to list again the definition of the previous “User” class, so you can recall more easily how it functions:


// define ‘User’ class

class User{

private $firstName;

private $lastName;

private $email;

public function __construct($firstName,$lastName,$email){

if(!$firstName||strlen($firstName)>32){

throw new Exception(‘Invalid First Name parameter!’);

}

if(!$lastName||strlen($lastName)>32){

throw new Exception(‘Invalid Last Name parameter!’);

}

if(!$email||!preg_match("/^.+@.+..+$/",$email)){

throw new Exception(‘Invalid Email parameter!’);

}

$this->firstName=$firstName;

$this->lastName=$lastName;

$this->email=$email;

}

// get user’s first name

public function getFirstName(){

return $this->firstName;

}

// get user’s last name

public function getLastName(){

return $this->lastName;

}

// get user’s email

public function getEmail(){

return $this->email;

}

// get all user data

public function getAll(){

return ‘First Name: ‘.$this->firstName.’ Last Name: ‘.$this->lastName.’ Email Address: ‘.$this->email;

}

// implement a __destruct()’ method

public function __destruct(){

// display object properties

echo ‘<h2>Properties of object being destroyed</h2>';

foreach(get_object_vars($this) as $prop=>$val) {

 echo ‘<p>’.$prop.’=’.$val.'</p>';

 }

// display object methods

echo ‘<h2>Methods of object being destroyed</h2>';

$methods=get_class_methods(get_class($this));

foreach($methods as $method) {

echo ‘<p> Method Name: ‘.$method.'()</p>';

}

}

}


Having listed the signature corresponding to the sample “User” class, now it’s time to demonstrate how to manually trigger the respective destructors of a few user handling objects when they’re removed by way of the “unset()” PHP function.

This process is performed neatly by the  hands-on example below, thus I recommend that you have a close look at it:


try{

// create first user

$user1=new User(‘John’,’Doe’,’john@domain.com’);

// display separately user data

echo ‘First Name: ‘.$user1->getFirstName().'<br />';

echo ‘Last Name: ‘.$user1->getLastName().'<br />';

echo ‘Email: ‘.$user1->getEmail().'<br />';

// display all user information

echo ‘Complete user information: ‘.$user1->getAll();

 

// delete object, this triggers its ‘__destruct()’ method

echo ‘<h2>Calling destructor method of first user object!</h2>';

unset($user1);

// create second user

$user2=new User(‘Mary’,’Smith’,’mary@domain.com’);

// display separately user data

echo ‘First Name: ‘.$user2->getFirstName().'<br />';

echo ‘Last Name: ‘.$user2->getLastName().'<br />';

echo ‘Email: ‘.$user2->getEmail().'<br />';

// display all user information

echo ‘Complete user information: ‘.$user2->getAll();

 

// delete object, this triggers its ‘__destruct()’ method

echo ‘<h2>Calling destructor method of second user object!</h2>';

unset($user2);

// create third user

$user3=new User(‘Susan’,’Norton’,’susan@domain.com’);

// display separately user data

echo ‘First Name: ‘.$user3->getFirstName().'<br />';

echo ‘Last Name: ‘.$user3->getLastName().'<br />';

echo ‘Email: ‘.$user3->getEmail().'<br />';

// display all user information

echo ‘Complete user information: ‘.$user3->getAll();

 

/* displays the following

 

First Name: John

Last Name: Doe

Email: john@domain.com

Complete user information: First Name: John Last Name: Doe Email Address: john@domain.com

 

Calling destructor method of first user object!

Properties of object being destroyed

firstName=John

lastName=Doe

email=john@domain.com

 

Methods of object being destroyed

Method Name: __construct()

Method Name: getFirstName()

Method Name: getLastName()

Method Name: getEmail()

Method Name: getAll()

Method Name: __destruct()

 

First Name: Mary

Last Name: Smith

Email: mary@domain.com

Complete user information: First Name: Mary Last Name: Smith Email Address: mary@domain.com


Calling destructor method of second user object!

Properties of object being destroyed

firstName=Mary

lastName=Smith

email=mary@domain.com

 

Methods of object being destroyed

Method Name: __construct()

Method Name: getFirstName()

Method Name: getLastName()

Method Name: getEmail()

Method Name: getAll()

Method Name: __destruct()


First Name: Susan

Last Name: Norton

Email: susan@domain.com

Complete user information: First Name: Susan Last Name: Norton Email Address: susan@domain.com

Properties of object being destroyed


firstName=Susan

lastName=Norton

email=susan@domain.com

 

Methods of object being destroyed

Method Name: __construct()

Method Name: getFirstName()

Method Name: getLastName()

Method Name: getEmail()

Method Name: getAll()

Method Name: __destruct()


*/

}

catch(Exception $e){

echo $e->getMessage();

exit();

}


That wasn’t rocket science, was it? As you can see by the above example, three different user handling objects are first spawned, and then deleted with the “unset()” PHP function. Obviously, the consequences of doing this are that the respective constructors are called according to the order in which these objects are removed.

Quite possibly at this very moment you’re wondering if it’s really useful to trigger destructors manually. Well, in certain conditions you might want to trigger these methods “behind the scenes” without having to terminate the execution of a specific PHP script. However, this depends completely on the application you’re working with and it’s up to you to decide when (if ever) to use this approach.

So far, so good. At this stage, I’m reasonably sure that you learned an alternative approach to call destructors manually. Nonetheless, it’s fair to mention that all the code samples that I built worked with PHP 5. So, there’s a question that remains unanswered: is it possible to emulate the behavior of destructors in PHP 4? Of course it is! And the last section will be entirely focused on discussing this process in detail.

Go ahead and read the next few lines. We’re almost finished!

{mospagebreak title=Emulating destructors in PHP 4}

While PHP 4 indeed doesn’t directly support the implementation of destructors, as does PHP 5, the behavior of these methods can be emulated by using the PHP “register_shutdown_function()” function, which, as its name suggests, permits it to specify what user-defined function will be called when a script terminates its execution.

Of course, this function can be used with both procedural and object-oriented approaches. In this case I’m going to teach you how to use it within the same “User” class that you saw in previous sections, allowing the definition of a concrete method that will be invoked when a particular user handling object is destroyed by the PHP interpreter.

Naturally, this behavior closely resembles the one exposed by a destructor in PHP 5. So in taking advantage of this, below I listed the signature of the prior “User” class in order to function with PHP 4. Here’s how the pertinent class now looks:


// define ‘User’ class

class User{

var $firstName;

var $lastName;

var $email;

function User($firstName,$lastName,$email){

if(!$firstName||strlen($firstName)>32){

trigger_error(‘Invalid First Name parameter!’,E_USER_ERROR);

}

if(!$lastName||strlen($lastName)>32){

trigger_error(‘Invalid Last Name parameter!’,E_USER_ERROR);

}

if(!$email||!preg_match("/^.+@.+..+$/",$email)){

 trigger_error(‘Invalid Email parameter!’,E_USER_ERROR);

}

$this->firstName=$firstName;

$this->lastName=$lastName;

$this->email=$email;

register_shutdown_function(array($this,’customShutdown’));

}

// get user’s first name

function getFirstName(){

return $this->firstName;

}

// get user’s last name

function getLastName(){

return $this->lastName;

}

// get user’s email

function getEmail(){

return $this->email;

}

// get all user data

function getAll(){

return ‘First Name: ‘.$this->firstName.’ Last Name: ‘.$this->lastName.’ Email Address: ‘.$this->email;

}

// define class method for being called when the script finishes its execution

function customShutdown(){

// display object properties

echo ‘<h2>Properties of current object</h2>';

foreach(get_object_vars($this) as $prop=>$val) {

 echo ‘<p>’.$prop.’=’.$val.'</p>';

}

// display object methods

echo ‘<h2>Methods of current object</h2>';

$methods=get_class_methods(get_class($this));

foreach($methods as $method) {

echo ‘<p> Method Name: ‘.$method.'()</p>';

}

}

}


As you can see, at first sight the above user handling class looks very similar to its PHP 5 incarnation; however, you should pay attention to the definition of its constructor, since here is where all the action takes place. The following line within this class method:


register_shutdown_function(array($this,’customShutdown’));


indicates that a “customShutdown()” method will be called when an object of the “User” class is deleted, in this manner emulating the behavior of a real destructor. Quite simple, right?

Assuming that you already grasped how to implement the PHP “register_shutdown_function()” as part of a class API, please study the following example, which demonstrates how the “customShutdown()” method is neatly called when a sample user object is destroyed by the PHP engine. Here it is:


// create user object

$user1=&new User(‘John’,’Doe’,’john@domain.com’);

// display separately user data

echo ‘First Name: ‘.$user1->getFirstName().'<br />';

echo ‘Last Name: ‘.$user1->getLastName().'<br />';

echo ‘Email: ‘.$user1->getEmail().'<br />';

// display all user information

echo ‘Complete user information: ‘.$user1->getAll();


/* displays the following


First Name: John

Last Name: Doe

Email: john@domain.com

Complete user information: First Name: John Last Name: Doe Email Address: john@domain.com


Properties of current object

firstName=John

lastName=Doe

email=john@domain.com


Methods of current object

Method Name: User()

Method Name: getFirstName()

Method Name: getLastName()

Method Name: getEmail()

Method Name: getAll()

Method Name: customShutdown()


*/


In this case, you can see that the previous “User” class now has a method that closely resembles the behavior of the native destructor in PHP 5, since when the above script finishes running (and the pertinent user object is consequently deleted), the “customShutdown()” method is properly invoked.

Here you have it. From this point onward, you may want try defining some classes with PHP 4 and implementing a few pseudo destructor methods within them. It’s going to be an instructive experience, believe me!

Final thoughts

It’s hard to believe, but we’ve come to the end of this series. Overall, the experience has been instructive and also fun. As you saw in the different tutorials, destructors aren’t going to change your life as a PHP developer forever, but they can be potentially useful in certain cases.

Tracking the status of a bunch of objects is probably one of its most popular uses, but this doesn’t necessarily mean that they can only be applied to perform this task. So fire up your inspiration and start using destructors in a creative way!

See you in the next PHP development tutorial!

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

antalya escort bayan antalya escort bayan Antalya escort diyarbakir escort