stutstut.dev

Snippet: Singletons with PHP

Today’s snippet describes the singleton pattern. The singleton pattern is a method of creating a class that statically maintains an instance of itself and ensures that no other instances can be created. This is useful for classes that implement app-wide services such as logging, DB access and other shared resources.

The basic requirements for a singleton class are as follows…

That’s basically it. Here’s a simple example…

class Singleton
{
  static private $_instance = null;

  public static function & Instance()
  {
    if (is_null(self::$_instance)) {
      self::$_instance = new self();
    }
    return self::$_instance;
  }

  private function __construct()
  {
    // Do normal instance initialisation here
    // Nothing singleton-related should be present
  }

  public function __destruct()
  {
    // This is just here to remind you that the
    // destructor must be public even in the case
    // of a singleton.
  }

  public function __clone()
  {
    trigger_error('Cloning instances of this class is forbidden.', E_USER_ERROR);
  }

  public function __wakeup()
  {
    trigger_error('Unserializing instances of this class is forbidden.', E_USER_ERROR);
  }

  private $var = '';

  public function SetVar($val)
  {
    $this->var = $val;
  }

  public function GetVar()
  {
    return $this->var;
  }
}

This is an extremely simple example but it demonstrates all of the core concepts. You use this class as follows…

$obj1 = Singleton::Instance();
$obj1->SetVar('some value');

$obj2 = Singleton::Instance();
echo $obj2->GetVar(); // This will echo 'some value'

If you attempt to clone or unserialize an instance your script will fail with an error. I use this pattern all over the place and definitely recommend using it where it makes sense in your applications. An alternative would be to implement the entire class statically and to be honest I’m not sure whether there are advantages to either implementation. If someone knows please share in the comments.

That’s it for this snippet, stay tuned for more. As always comments, questions, suggestions and requests are welcomed.