Sep 23 2009
Singletons in PHP
I write PHP regularly in my job, but this is the first post on Ashita.org on a PHP subject. One interesting problem recently was how to make Singletons in PHP from a generic base class and extended where necessary. First, an introduction: Singletons are an incredibly common and useful design pattern. Singletons are used to ensure there is only one instance of a class and the class cannot be instantiated directly from outside the class.
-
Simple Case
In PHP, the singleton pattern is as easy as making a class with a private or protected constructor and a static method to get the single instance.
class Singleton { private $instance; private function __construct() { } private function __clone() { //do nothing } public static function getInstance() { if (is_null(self::$instance)) { self::$instance = new self(); } return self::$instance; } }-
Note
One thing to note about the code above is the
__clone()method. Unless overridden, the default __clone() method creates a new object with all of the properties copied over. Obviously, this goes against the principles of a singleton — there should be only one instance.
This technique allows the class author to ensure only one instance is available and that any changes made to it are shared by all references to this object, but what if we wanted to use this pattern more than once. Wouldn’t it be better to extend this class? Doing so would require some changes… (and in this implementation, it requires php 5.3 or higher)
-
-
Extendable Singleton
abstract class Singleton { public static function getInstance() { $class = get_called_class(); if (is_null($class::$instance)) { $class::$instance = new $class(); } return $class::$instance; } } class Database extends Singleton { protected static $instance; protected function __construct() { //do DB init work here } private function __clone() { } //include functions to act on DB here }basically, the only thing classes extending Singleton would need to do is mark their
__constructmethod protected, their__clonemethod can remain private, and to include aprotected static $instanceclass variable. Further simplifications could be made, but it seems a good base to work from. (Note that the above example requires a somewhat quirky behaviour in php that allows subclasses to inherit static methods.)
