What is the Singleton pattern?
The Singleton pattern is a design pattern which restricts instantiation of a class to one single object.
This can be useful for code optimization (instead of wasting memory by instantiating the same class multiple times, you can instantiate it only once and use that instance), limited resources (lets say you have a database class which you instantiate in your other classes, this means that for every instance you are opening a database connection, even if you use only one; by using the Singleton pattern you will open only one database connection so the risk of reaching MySQL maximum connection limit will be lower).
Code implementation for the Singleton pattern in PHP
Lets suppose we have this database class :
class DB{ public function __construct(){ //... } public function connect($data){ //... } public function insert($where, $fields, $values){ //... } }
when we want to instance it we use the "new" operator like this :
$object = new DB();
this will happen for every object where you need to use the DB class and will mean .. a database connection and memory allocation for every new object.
To modify this class to use the Singleton pattern we need to follow the next steps :
1) add a protected static property to the class
protected static $instance;
2) make the class constructor private so it can't be called outside the class :
private function __construct(){ //... }
3) write the class method to return our Singleton :
public static function getInstance() { if (!isset(self::$instance)) { self::$instance = new __CLASS__; } return self::$instance; }
4) make use of the magic function __clone to prevent users from cloning the object itself :
public function __clone() { die(__CLASS__ . ' class can\'t be instantiated. Please use the method called getInstance.'); }
The new class should be like this :
class DB{ protected static $instance; private function __construct(){ //... } public function connect($data){ //... } public static function getInstance() { if (!isset(self::$instance)) { self::$instance = new __CLASS__; } return self::$instance; } public function __clone() { die(__CLASS__ . ' class can\'t be instantiated. Please use the method called getInstance.'); } public function insert($where, $fields, $values){ //... } }
and from now on, instead of using the new operator to create new object instances we will use the getInstance method :
$obj1 = $DB::getInstance(); $obj2 = $DB::getInstance();
which will bring an instance of the DB class.