Base class for singletons Even though singletons are bad practice and often unnecessary, I still see many developers using this pattern over and over. Since implementation of this pattern usually requires some common code, I thought we could just make a base class to be extended.

I came up with this so far.

&lt;?php
namespace wl;


/**
 * @dosc allows only one instance for each extending class
 * @example use it for database connection, config setup...
 * Be aware, the singleton pattern is consider to be an anti-pattern
 * because it can be hard to debug.
 * In most cases you do not need to use singleton pattern
 * so take a longer moment to think about it before you use it.
 */
class Singleton
{
    /**
     *  holds an single instance of a class
     *
     *  @var array of objects
     */
    protected static $instance = [];

    /**
     *  @desc provides a single slot to hold an instance interchanble between all child classes.
     *  @return object
     */
    public static function getInstance(){
        $class = get_called_class();
        if(!isset(self::$instance[$class]) || !self::$instance[$class] instanceof $class){
            self::$instance[$class] = new static(); // create and instance of child class which extends Singleton super class
            echo "new ". $class . PHP_EOL; // remove this line after testing
            return  self::$instance[$class]; // remove this line after testing
        }
        echo "old ". $class . PHP_EOL; // remove this line after testing
        return static::$instance[$class];
    }

    /**
     *  do not allow create new instance by new keyword
     * 
     */
    protected function __construct(){}

    /**
     *  Do not clone the object
     */
    protected function __clone(){}

    /**
     *  Do not allow reserialization of this object
     */
    protected function __wakeup(){}

}




/**
 * ----------------------------------------------USE EXAMPLE---------------------------------------------------
 *  @docs example database class by extending singleton class implements singleton pattern
 */
class Database extends Singleton
{
    public function __construct(){

    }
}


/**
 *  @docs Config class by extending singleton class implements singleton pattern
 */
class Config extends Singleton
{
    public function __construct(){

    }
}

/**
 *  @example create new Database
 */
$bd1 = Database::getInstance(); // new
$bd2 = Database::getInstance(); // old

/**
 *  @example create new Config 
 */
$bd1 = Config::getInstance(); // new
$bd2 = Config::getInstance(); // old



$bd3 = Config::getInstance(); // old
$bd4 = Database::getInstance(); // old

$bd5 = Database::getInstance(); // old
$bd6 = Config::getInstance(); // old


Any suggestions are very welcome.
github
Not a Singleton


class Database extends Singleton
{
    public function __construct(){

    }
}



This is not a singleton.  Add the following code:  

$bd7 = new Config();


You have a new Config object.  

class Config extends Singleton {

    protected function __construct() {

    }

}


This is a singleton.  It will give an error if you try to create a Config object directly.  Or 

class Database extends Singleton {

}


Is a singleton that gives an error if you create a Database object directly as it inherits its constructor from its parent.  

Registry

You don't need to use inheritance to get this functionality.  


    public static function getInstance(){
        $class = get_called_class();
        if(!isset(self::$instance[$class]) || !self::$instance[$class] instanceof $class){
            self::$instance[$class] = new static(); // create and instance of child class which extends Singleton super class
            echo "new ". $class . PHP_EOL; // remove this line after testing
            return  self::$instance[$class]; // remove this line after testing
        }
        echo "old ". $class . PHP_EOL; // remove this line after testing
        return static::$instance[$class];
    }



Change to 

    public static function getInstance($class, $object = null) {
        if (!isset(self::$instance[$class]) &amp;&amp; $object != null) {
            self::$instance[$class] = $object;
        }

        return static::$instance[$class];
    }


or just 

    public static function getInstance($key) {
        return static::$instance[$key];
    }


with 

    public static function setInstance($key, $object) {
        static::$instance[$key] = $object;
    }


And change 


$bd1 = Database::getInstance(); // new



to 

Registry::setInstance('database', new Database());
$bd1 = Registry::getInstance('database');


Now, it's possible that in a real application you would make more use of what inheritance gives you.  But in this toy application, you don't.  

I changed the name from Singleton to Registry, as better fitting this pattern.  

You lose the just-in-time instantiation of the original, but you gain control over how it is instantiated.  An advantage of this form is that you can also do things like 

Registry::setInstance('database', new MockDatabase());


Your original form prevented this, exacerbating the Singleton pattern's problems with user testing.  

Nitpicks


/**
 * @dosc allows only one instance for each extending class
 * @example use it for database connection, config setup...
 * Be aware, singleton pattern is consider to be an antipatern and becaouse of it build it is hard to debug.
 * In most cases you do not need to use singleton patern so make a longer moment to think about it befor you use it.
 */



Without the spelling errors:  

/**
 * @dosc allows only one instance for each extending class
 * @example use it for database connection, config setup...
 * Be aware, the singleton pattern is consider to be an anti-pattern
 * because it can be hard to debug.
 * In most cases you do not need to use singleton pattern
 * so take a longer moment to think about it before you use it.
 */


I also changed the wording a bit and broke up two lines so that they don't cause scrolling (at least in my browser).