Friday, February 13, 2015

Php's Constructors and Destructors

Constructors and Destructors

When creating a new object, often it's useful to set up certain aspects of the object at the same time. For example, we might want to set some properties to initial values, fetch some information from a database to populate the object, or register the object in some way.

Similarly, when it's time for an object to disappear, it can be useful to tidy up aspects of the object, such as closing any related open files and database connections, or unsetting other related objects.

Like most OOP languages, PHP provides us with two special methods to help with these tasks. An object's constructor method is called just after the object is created, and its destructor method is called just before the object is freed from memory.

In the following sections we learn how to create and use constructors and destructors.

Setting Up New Objects with Constructors

Normally, when we create a new object based on a class, all that happens is that the object is brought into existence. (Usually we then assign the object to a variable or pass it to a function.) By creating a constructor method in our class, however, we can cause other actions to be triggered when the object is created.

To create a constructor, simply we add a method with the special name __construct() to our class. (That's two underscores, followed by the word "construct," followed by parentheses.) PHP looks for this special method name when the object is created; if it finds it, it calls the method.

Here's a simple example:

 class MyClass
 {
   function __construct()
 {
     echo "Whoa! I've come into being.<br />";
   }
 }
 
 $obj = new MyClass;  // Displays "Whoa! I've come into being."


The class, MyClass, contains a very simple constructor that just displays the message. When the code then creates an object from that class, the constructor is called and the message is displayed.

We can also pass arguments to constructors, just like normal methods. This is great for setting certain properties to initial values at the time the object is created. The following example shows this principle in action:

 class Person
 {
   private $_firstName;
   private $_lastName;
   private $_age;
 
   public function __construct( $firstName, $lastName, $age )
 {
     $this->_firstName = $firstName;
     $this->_lastName = $lastName;
     $this->_age = $age;
   }
 
   public function showDetails()
 {
     echo "$this->_firstName $this->_lastName, age $this->_age<br />";
   }
 }
 
 $p = new Person( "Harry", "Walters", 28 );
 $p->showDetails();  // Displays "Harry Walters, age 28"


The Person class contains three private properties and a constructor that accepts three values, setting the three properties to those values. It also contains a showDetails() method that displays the property values. The code creates a new Person object, passing in the initial values for the three properties. These arguments get passed directly to the __construct() method, which then sets the property values accordingly. The last line then displays the property values by calling the showDetails() method.

If a class contains a constructor, it is only called if objects are created specifically from that class; if an object is created from a child class, only the child class's constructor is called. However, if necessary we can make a child class call its parent's constructor with parent::__construct().

Cleaning Up Objects with Destructors

Destructors are useful for tidying up an object before it's removed from memory. For example, if an object has a few files open, or contains data that should be written to a database, it's a good idea to close the files or write the data before the object disappears.

We create destructor methods in the same way as constructors, except that we use __destruct() rather than __construct():

  function __destruct()
 {
     // (Clean up here)
 }


Note that, unlike a constructor, a destructor can't accept arguments.

An object's destructor is called just before the object is deleted. This can happen because all references to it have disappeared (such as when the last variable containing the object is unset or goes out of scope), or when the script exits, either naturally or because of an error of some sort. In each case, the object gets a chance to clean itself up via its destructor before it vanishes.

Here's an example that shows this concept:

class Person
 {
   public function save()
 {
     echo "Saving this object to the database...<br />";
  }
 
   public function __destruct()
 {
     $this->save();
   }
 }
 
 $p = new Person;
 unset( $p );
 $p2 = new Person;
 die( "Something's gone horribly wrong!<br />");


This code displays the following output:

 Saving this object to the database...
 Something's gone horribly wrong!
 Saving this object to the database...


This Person class contains a destructor that calls the object's save() method to save the object's contents to a database before the object is destroyed. (In this example, nothing is actually saved; instead the message "Saving this object to the database..." is displayed.)

A new Person object is created and stored in the variable $p. Next, $p is removed from memory using the built-in unset() function. Doing this removes the only reference to the Person object, so it's deleted. But just before it's removed, its __destruct() method is called, displaying the message "Saving this object to the database...".

Next the code creates another Person object, storing it in the variable $p2. Finally, the code raises an error using the built-in die() function, which causes the script to end with a "Something's gone horribly wrong!" message. Just before the script finally terminates, however, the object's destructor is called, displaying the "Saving this object to the database..." message.

As with constructors, a destructor of a parent class is not called when the child object is deleted, but we can explicitly call a parent's destructor with parent::__destruct().

No comments:

Post a Comment