Searching...
Saturday 27 July 2013

Using Constructors and Destructors in PHP


Often, you’ll want to execute a number of tasks when creating and destroying objects. For example, you might want to immediately assign several properties of a newly instantiated object. However, if you have to do so manually, you’ll almost certainly forget to execute all of the required tasks. Object-oriented programming goes a long way toward removing the possibility for such errors by offering special methods, called constructors and destructors, that automate the object creation and destruction processes.

Constructors

You often want to initialize certain properties and even trigger the execution of methods (more about methods in PHP) found when an object (more about objects in PHP) is newly instantiated. There’s nothing wrong with doing so immediately after instantiation, but it would be easier if this were done for you automatically. Such a mechanism exists in OOP, known as a constructor. Quite simply, a constructor is defined as a block of code that automatically executes at the time of object instantiation. OOP constructors offer a number of advantages:
  • Constructors can accept parameters, which are assigned to specific object properties at creation time.
  • Constructors can call class methods or other functions.
  • Class constructors can call on other constructors, including those from the class parent.

This section reviews how all of these advantages work with PHP 5’s improved constructor functionality.

Note: PHP 4 also offered class constructors, but it used a different, more cumbersome syntax than the one used in version 5. Version 4 constructors were simply class methods of the same name as the class they represented. Such a convention made it tedious to rename a class. The new constructor-naming convention resolves these issues. For reasons of compatibility, however, if a class is found to not contain a constructor satisfying the new naming convention, that class will then be searched for a method bearing the same name as the class; if located, this method is considered the constructor.

PHP recognizes constructors by the name __construct (a double underscore precedes the constructor keyword). The general syntax for constructor declaration follows:

function __construct([argument1, argument2, ..., argumentN])
{
// Class initialization code
}


As an example, suppose you want to immediately populate certain book properties with information specific to a supplied ISBN. For example, you might want to know the title and author of a book, in addition to how many copies the library owns and how many are presently available for loan. The code might look like this:

<?php
class Book
{
private $title;
private $isbn;
private $copies;
function __construct($isbn)
{
$this->setIsbn($isbn);
$this->getTitle();
$this->getNumberCopies();
}
public function setIsbn($isbn)
{
$this->isbn = $isbn;
}
public function getTitle() {
$this->title = "Easy PHP Websites with the Zend Framework";
print "Title: {$this->title}<br />";
}
public function getNumberCopies() {
$this->copies = "5";
print "Number copies available: {$this->copies}<br />";
}
}
$book = new book("0615303889");
?>

This results in the following:

Title: Easy PHP Websites with the Zend Framework
Number copies available: 5

Of course, a real-life implementation would likely involve somewhat more intelligent get methods (e.g., methods that query a database), but the point is made. Instantiating the book object results in the automatic invocation of the constructor, which in turn calls the setIsbn(), getTitle(), and getNumberCopies() methods. If you know that such methods should be called whenever a new object is instantiated, you’re far better off automating the calls via the constructor than attempting to manually call them yourself.

Additionally, if you would like to make sure that these methods are called only via the constructor, you should set their scope to private, ensuring that they cannot be directly called by the object or by a subclass.

Invoking Parent Constructors

PHP does not automatically call the parent constructor; you must call it explicitly using the parent keyword. An example follows:

<?php
class Employee
{
protected $name;
protected $title;
function __construct()
{
echo "<p>Employee constructor called!</p>";
}
}
class Manager extends Employee
{
function __construct()
{
parent::__construct();
echo "<p>Manager constructor called!</p>";
}
}
$employee = new Manager();
?>

This results in the following:

Employee constructor called!
Manager constructor called!

Neglecting to include the call to parent::__construct() results in the invocation of only the Manager constructor, like this:

Manager constructor called!

Invoking Unrelated Constructors

You can invoke class constructors that don’t have any relation to the instantiated object simply by prefacing __construct with the class name, like so:

classname::__construct()

As an example, assume that the Manager and Employee classes used in the previous example bear no hierarchical relationship; instead, they are simply two classes located within the same library. The Employee constructor could still be invoked within Manager’s constructor, like this:

Employee::__construct();

Calling the Employee constructor in this manner results in the same outcome shown in the example.

Destructors


Just as you can use constructors to customize the object creation process, so can you use destructors to modify the object destruction process. Destructors are created like any other method but must be titled __destruct(). An example follows:

<?php
class Book
{
private $title;
private $isbn;
private $copies;
function __construct($isbn)
{
echo "<p>Book class instance created.</p>";
}
function __destruct()
{
echo "<p>Book class instance destroyed.</p>";
}
}
$book = new Book("0615303889");
?>

Here’s the result:

Book class instance created.
Book class instance destroyed.

When the script is complete, PHP will destroy any objects that reside in memory. Therefore, if the instantiated class and any information created as a result of the instantiation reside in memory, you’re not required to explicitly declare a destructor. However, if less volatile data is created (say, stored in a database) as a result of the instantiation and should be destroyed at the time of object destruction, you’ll need to create a custom destructor.


3 comments:

 
Back to top!