PHP Programming/Special Methods

Constructors

edit

A constructor is a special method inside a class that is called when the object is initiated. A constructor could be used as follows:


This is the PHP5 Version:

  <?php
  class test {
    public $name;   
    public function __construct ($name) {
        $this->name = $name;
     }
  }
  $testing = new test('Hello');
  echo $testing->name;  // Prints 'Hello'
  ?>

This is the equivalent PHP4.x Version: (Note that there are no public/private keywords, and the name of the class is the constructor)

  <?php
  class test {
    var $name;   
    function test ($name) {
        $this->name = $name;
     }
  }
  $testing = new test('Hello');
  echo $testing->name;  // Prints 'Hello'
  ?>

In PHP5 a constructor must be declared as public or it will not work. The name of a constructor must always be __construct in PHP5.The name of the class must be used as a constructor in PHP5.

Destructors

edit

Destructors delete an instance of an object. The destructor is declared within the object's class, and contains other code to be executed at the time of destruction:

   <?php
   class myClass {
     function __construct() {
         print "Constructing new myClass...\n";
         $this->name = "My class";
     }
     function __destruct() {
         print "Destroying " . $this->name . "\n";
     }
   }
   $obj = new myClass();
   ?>

Note that destructors only exist in PHP5.

Why Constructors and Destructors Are Great

edit

Why are constructors and destructors useful? Sometimes objects represent complex entities that use other resources or have other side effects, even though they appear as simple variables in your program. In these cases, special setup may be required when you create the object; you can use the constructor to do that automatically for you. Also, it can be very important to free those resources at the end of your program so that they don't get tied up from multiple runs or pageviews; the destructor can automatically handle that so you don't forget.

Here's an example that makes handling MySQL databases slightly simpler:

 <?php
 class db_link {
  private $link;
  public function __construct ($database_name) {
   $link = mysql_connect ("localhost", "your_user_name", "your_password");
   mysql_select_db ($database_name, $link);
   $this -> link = $link;
   }
  function query ($sql_query) {
   $result = mysql_query ($sql_query, $this -> link);
   return $result;
   }
  function __destruct() {
   mysql_close ($this -> link);
   }
  }
 $db = new db_link ("MyDB");
 $result = $db->query ("Select * from MyTable");
 ?>

The class "db_link" uses 3 functions: the constructor, which automatically logs into the database for me whenever I create a new "db_link" object, a "query" function, which I can use to get records from the database, and the destructor, which automatically closes the database whenever PhP is finished with my object instance. I could do the same things as the constructor and destructor by writing special "open" and "close" functions for the database, but then I would have to call those functions every time. This way, all I have to do is make objects and use them; they can open and close themselves automatically.


Serialization and Unserialization

edit

In certain cases, it is necessary to store an instantiated(created) object as static text for storage between program runs, usually in a file or database field. This can be stored using serialization, which creates a string from an object that can then be unserialized into a working object, including working methods and properties.

An object can be serialized with:

 <?php
 class test {
  private $test1;
  public function __construct ($testval) {
   $this->test1=$testval;
   }
  public function get_testval() {
   return $testval;
   }
  }
 $testobject = new test ("Testing serialization...")
 $serialized_testobject = serialize($testobject);
 ?>

$serialized_testobject is a string that can then be stored as text in a file or database column, assuming it does not exceed the size limit for the column. It can be unserialized with:

 <?php
 class test {
  private $test1;
  public function __construct ($testval) {
   $this->test1=$testval;
   }
  public function get_testval() {
   return $testval;
   }
  }
 $testobject = unserialize($serialized_testobject);
 echo $testobject->get_testval();
 ?>

Note that the test class needs to be defined as it is not defined in the serialized string. Defining the class in a different way may cause problems when unserializing. The class must have the same name.

Certain objects, however, will need to perform tasks before and after serializing to ensure consistency between runs. For example, database links will need to be destroyed when serializing and recreated when unserializing, or they will be invalidated later. The object is prepared for serialization during the user-defined __sleep() method, and is prepared for work after unserializing with __wakeup(), as shown below.

 <?php
 class db_link {
  private $link;
  public function __construct ($database_name) {
   $link = mysql_connect ("localhost", "your_user_name", "your_password");
   mysql_select_db ($database_name, $link);
   }
  function query ($sql_query) {
   $result = mysql_query ($sql_query, $link);
   return $result;
   }
  function __destruct() {
   mysql_close ($link);
   }
  function __sleep() {
   mysql_close ($link);
  }
  function __wakeup() {
   $link = mysql_connect ("localhost", "your_user_name", "your_password");
   mysql_select_db ($database_name, $link);
  }
 $db = new db_link ("MyDB")
 $result = $db->query ("Select * from MyTable")
 ?>

Here, the link is closed when serializing, and reopened when unserializing as the link would probably not have the same network state if stored in a text file for a few hours. In complex classes, many properties and other data not highly dependent on time would be stored in the serialized string, while more volatile things like file handles and database links would be closed and reopened later. An exception does exist: Large amounts of data that can be quickly generated should be destroyed or at least compacted in __sleep() so they do not take up space in the serialized file. For example, an array containing algorithmically-generated entries that is 2000 entries long should be regenerated.