PHP Design Patterns - Singleton Patterns

Keywords: PHP

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

Posted by techiefreak05 on Fri, 25 Jan 2019 14:24:14 -0800