Dobromir Yordanov
Dobromir Yordanov

Reputation: 89

PHP singletons and inheritance

I'm having some trouble with PHP Inheritance. Here's deal:

I have this base class, Singleton:

namespace My_Namespace;

abstract class Singleton {
    protected static $instance = null;

    static function get() {
        if ( null == static::$instance ) {
            static::$instance = new static;
        }
        return static::$instance;
    }

    private function __construct() {

    }
}

I have a bunch of classes inheriting that Singleton class, call them A,B,C,D. One of them looks like this:

namespace My_Namespace;

class A extends Singleton {

    protected function __construct() {

        B::get();

        if ( some_condition() ) {
            C::get();
        }
        else {
            D::get();
        }
    }
}

Now, I just do a A::get() to get it all rolling. The constructor of A is called, as expected. Then, the constructor of B is called, again without a problem. Now it gets weird. Once C::get() is called, it recognizes static::$instance as already an object of class B and doesn't instantiate C at all. I know if I kinda daisy-chain them, that is __construct of B calls C::get or D::get it works but that's not optimal for my purposes. Is that caused by them being in the same scope? If so, is there any way around this? I'm asking this more of curiosity rather than practical purpose - I know I can just as easily implement the singleton pattern in each one of them. So, any ideas? Thanks!

P.S. Please no 'singletons are evil and you should burn in hell' comments. I know that perfectly well.

Upvotes: 5

Views: 1078

Answers (2)

bpoiss
bpoiss

Reputation: 14003

Note that static::$instance = new static calls the constructor of (in your case) A.

With your solution, you will need a static property for your instance in your subclasses.

Just add

protected static $instance = null;

to them, and it should work fine.

Upvotes: 2

Orangepill
Orangepill

Reputation: 24645

When dealing with static properties if you want the inherited classes's static properties to differ from the base classes you have to provide a home for it to live in.

To solve the problem just define

protected static $instance = null;

on your derived class. If not it will use the base class' property.

Upvotes: 1

Related Questions