maček
maček

Reputation: 77778

How to subclass a Singleton in PHP?

I'm trying to subclass a class that uses singleton pattern and populate the instance with the subclass.

I seem to be having a little trouble.

class Singleton {

    static private $instance;

    static public function instance(){
        if(is_null(self::$instance)){
            self::$instance = new self();
        }
        return self::$instance;
    }

    private function __construct(){}

}

class MySingleton extends Singleton {

}

echo get_class(MySingleton::instance()); //=> Singleton

//=> I'm hoping to see MySingleton

Upvotes: 6

Views: 880

Answers (3)

ggsonic
ggsonic

Reputation: 11

this works

<?php

class Singleton {

    static private $instance;
    static public function instance(){
        static $instance = null;  
        return $instance ?: $instance = new static;
    }

    public function __construct(){}

}

class MySingleton extends Singleton {
}

But i recommend the following one:

<?php
class Singleton {

    static protected $instance;              //should not be private

    static public function instance(){
        if(is_null(static::$instance)){         
            static::$instance = new static();
        }
        return static::$instance;

    }

    public function __construct(){}

}

class MySingleton extends Singleton {
    static protected $instance;    //must explicitly declared
}

Upvotes: 1

Kris
Kris

Reputation: 41827

Your singleton base class prevents that as is. if you change the code to this though, it will work.

<?php


class Singleton {

    static private $instances = array();

    static public function instance(){
        $class = get_called_class();
        if(!isset(self::$instances[$class])){
            self::$instances[$class] = new $class();
        }
        return self::$instances[$class];
    }

    private function __construct(){}

}

class MySingleton extends Singleton {

}

echo get_class(MySingleton::instance()); //=> MySingleton

Now it works because Singleton allows for one instance per child class.

Upvotes: 1

Michael Mior
Michael Mior

Reputation: 28752

What you're looking for is late static binding which is a new feature of PHP 5.3. Try replacing new self() with new static() and this should work for you.

self always references the containing class, whereas static references the "called" class.

Upvotes: 9

Related Questions