Sinlgeton Design Pattern With PHP5

9th February 2008 - 4 minutes read time

The singleton design pattern is used to centralise an object in an application that is used to store changing variables that can then be accessed by other parts of the program. It allows only the single instantiation of an object, hence the name.

The main use of a singleton is to create an alternative to the use of global variables. Although global variables are useful they can lead to a major problem if you happen to assign two variables with the same name, PHP generates no errors and your program will start to act oddly. This might not be a problem in small programs, but in larger systems it is very easy to have global variable clashes.

The singleton pattern gets around this by using an single object that is accessible to any part of the program that wants it. If two classes are declared with the same name PHP throws an error so if another part of the program tries to use the same class name you will know about it.

Another use of a singleton is to coordinate actions across a system. If two parts of a system use the same object a singleton can be used to stop the different parts of the system creating separate objects. With a singleton only a single object is ever created.

The first step in creating a singleton is to create the class in the usual form, but to make the constructor private. This means that it is not possible to instantiate the class directly. Next we set up a static variable and a static function, their static nature means that they are available even if the object is not instantiated.

The static variable is used to store an instance of the object. When the static function is called it checks to see if an object is held within the static variable, if it is then it returns that object, if it doesn't then a new object is created and returned. Here is some sample code of a class that can be used to store a single preference.

class Preferences
{
  private $property;
  public static $instance;
 
  private function __construct()
  {
  }
 
  public static function getInstance(){
    if (empty(self::$instance)) {
      self::$instance = new Preferences();
    }
    return self::$instance;
  }
 
  public function setProperty($value) 
  {
    $this->property = $value;
  }
 
  public function getProperty()
  {
    return $this->property;
  }
}

This class is used in the following manner.

$pref = Preferences::getInstance();
$pref->setProperty("nothing");

A more useful class is one that stored many different types of property as an array.

class Preferences
{
  private $property = array();
  public static $instance;
 
  private function __construct()
  {
  }
 
  public static function getInstance()
  {
    if (empty(self::$instance)) {
      self::$instance = new Preferences();
    }
    return self::$instance;
  }
 
  public function setProperty($key, $value)
  {
    $this->property[$key] = $value;
  }
 
  public function getProperty($key)
  {
    return $this->property[$key];
  }
}

This is used in the following manner.

$pref = Preferences::getInstance();
$pref->setProperty("property1", "nothing");

Due to the use of the get and set methods within the object Singletons cannot be overwritten with the wrong kind of data, which provides a further level of protection over the standard global variable.

It is very easy to use the singleton pattern in everything that you do, but it should be used only when you really need it. If something goes wrong with your program you can have a hard time in spotting what it is due to the difficulty of tracing relationships in a system build with singletons.

Add new comment

The content of this field is kept private and will not be shown publicly.