Singleton class

This is continuation from singleton pattern post.

Here’s the abstract class for singleton pattern, and other classes that need to be singleton just need to extend this class.

class singleton {
    private static $instance;
    private function __construct() {}
    private function __clone() {}
    protected static function init($class) {
        if (!isset(self::$instance[$class]) ||
            !self::$instance[$class] instanceof $class) {
            self::$instance[$class] = new $class();
        }
        return self::$instance[$class];
    }
}

We can’t directly use self::$instance = new self(); because self will refer to this singleton class itself, not the class we extend. So, to get the extending class, the extending class need to explicitly pass the classname to parent class to init().

class app extends singleton {
    var $i = 0;
    static function o() {
        return parent::init(__CLASS__);
    }
    function run() {
        $this->i++;
        echo 'run app...';
    }
}
// to access app class and its methods & attr
app::o()->run();
echo app::o()->i;

Singleton pattern

Singleton class is class that allow only one instance of its class to be instantiated.

A lot of examples I see the way to implement singleton pattern whether:

1. Extends a base singleton class
2. Each class apply singleton pattern (get_instance() method, has static $instance attribute)
3. Using registry pattern where one dedicated class act as the singleton instances manager

Well, things shouldn’t get too hard. Here, I will use the combination of registry pattern and singleton in just a function

function o($class) {
    static $instances;
    if (!isset($instances[$class]) || !$instances[$class] instanceof $class) {
        $instances[$class] =& new $class();
    }
    return $instances[$class];
}

To use it:

o('db')->query(...);
o('db')->fetch();
o('singleton_class')->do_something();