Singleton pattern is a common design pattern, which can be seen in many frameworks. Through the singleton pattern, we can ensure that there is only one instantiation of the class, which facilitates the control of the number of instances and saves system resources.
<?php use \Exception; class Singleton { /** * Object instance * @var object / public static $instance; /** * Getting instantiated objects / public static function getInstance() { if (!self::$instance instanceof self) { self::$instance = new self(); } return self::$instance; } /** * Prohibit objects directly from external instances / private function __construct(){} /** * Preventing cloning operations / final public function __clone() { throw new Exception('Clone is not allowed !'); } }
Singleton patterns may be used many times in a system. In order to create them more conveniently, we can try to build a general abstraction:
// SingletonFacotry.php <?php use \Exception; abstract class SingletonFacotry { /** * Object instance array * @var array / protected static $instance = []; /** * Getting instantiated objects / public static function getInstance() { $callClass = static::getInstanceAccessor(); if (!array_key_exists($callClass, self::$instance)) { self::$instance[$callClass] = new $callClass(); } return self::$instance[$callClass]; } abstract protected static function getInstanceAccessor(); /** * Prohibit objects directly from external instances / protected function __construct(){} /** * Preventing cloning operations / final public function __clone() { throw new Exception('Clone is not allowed !'); } }
// A.php <?php class A extends SingletonFactory { public $num = 0; protected static function getInstanceAccessor() { return A::class; } } $obj1 = A::getInstance(); $obj1->num++; var_dump($obj1->num); // 1 $obj2 = A::getInstance(); $obj2->num++; var_dump($obj2->num); // 2