Can 2 singleton classes refer to each other?

Why is this not working? Shouldn't each instance just refer to each other once?

class foo {
    private static $instance;
    private function __construct() {
    $test = bar::get_instance();
    }

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

class bar {
    private static $instance;
    public function __construct() {
    $test = foo::get_instance();
    }

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

$test = foo::get_instance();
+3
source share
4 answers

You have what is called circular addiction . It takes B to complete the construction, and B to complete A. Thus, this continues year-round.

In principle, what happens is that self::$instancefor each class it is not filled until new class()it ends. Therefore, in the constructor, you call another getInstance. But every time you click get_instance(), it self::$instanceremains zero, because the previous one newnever finished. And around and around. He will keep going until the end.

:

class foo {
    private static $instance;
    private function __construct() {
    }
    private function setBar(bar $bar) {
        $this->bar = $bar;
    }

    public static function get_instance() {
        if (empty(self::$instance)) {
            self::$instance = new foo();
            self::$instance->setBar(bar::get_instance());
        }
        return self::$instance;
    }
}

class bar {
    private static $instance;
    public function __construct() {
    }
    private function setFoo(foo $foo) {
        $this->foo = $foo;
    }
    public static function get_instance() {
        if (empty(self::$instance)) {
            self::$instance = new bar();
            self::$instance->setFoo(foo::get_instance());
        }
        return self::$instance;
    }
}

, , , .

+4

:

Foo:: get_instance(); → foo constructor → bar:: get_instance() → bar constructur → foo:: get_instance(); → ...

+3

. foo bar , .

0

. :

foo::get_instance() 
foo::__construct()
bar::get_instance()
bar::__construct()
foo::get_instance()
foo::__construct()
...

, , , foo:: get_Instance , foo::get_Instance $instance.

, , , .

If you do not need, you just call foo::get_Instanceand bar::get_instanceat the points that you need to access.

0
source

Source: https://habr.com/ru/post/1790094/


All Articles