开发者

Singleton reference and recursion in PHP

开发者 https://www.devze.com 2023-04-11 02:29 出处:网络
I have a main bootstrap class (singleton1 in the example bellow) that instantiates some singleton classes. In those singleton classes, I need to keep a reference to the app main class for easy and qui

I have a main bootstrap class (singleton1 in the example bellow) that instantiates some singleton classes. In those singleton classes, I need to keep a reference to the app main class for easy and quick reference to it, but doing so gives me a:

Fatal error: Maximum function nesting level of '100' reached, aborting

Here is the exmaple code:

<?php

class Singleton1 {

    private static $instance;


    private function __construct() {

        Singleton2::instance();

    }

    public static function instance () {

        if( !self::$instance ) {
            $class = __CLASS__;
            self::$instance = new $class;
        }

        return self::$instance;
    }

    public function test () {
        echo 'Good.';
    }

    private function __clone() { }

    private function __wakeup() { }

}

class Singleton2 {

    private static $instance;

    private $singleton1;

    private function __construct() {
        $this->singleton1 = Singleton1::instance();
    }

    public static function instance () {

        if( !self::$instance ) {
            $class = __CLASS__;
            self::$instance =开发者_如何学Python new $class;
        }

        return self::$instance;
    }

    public function test () {
        $this->singleton1->test();
    }

    private function __clone() { }

    private function __wakeup() { }

}

Singleton1::instance();

Singleton2::instance()->test();

I can't find any logical explanation to the issue ...

Thanks.


Your code has the following loop:

Singleton2::__construct()
Singleton1::instance()
Singleton1::__construct()
Singleton2::instance()
Singleton2::__construct()


You can remove Singleton2::instance() line from Singleton1 constructor to see "Good" message.


You should just not use Singletons. They're Bad Practice(tm), as they introduce global state, which makes your Code much harder to test.

One could rewrite your example by using Inversion Of Control this way:

<?php

// A simple Singleton for the Application
function Application()
{
     static $instance = null;

     if (null === $instance) {
         $instance = new Application;
     }
     return $instance;
}

class Application
{
     protected $someService;

     function __construct()
     {
         $this->someService = new SomeService($this);
     }

     function test()
     {
         echo "Good.";
     }
}

class SomeService
{
     protected $application;

     function __construct(Application $app)
     {
         $this->application = $app;
     }

     function test()
     {
         $this->application->test();
     }
}

Application is your Main Application's class and SomeService is your Singleton2.

No need for private constructors, etc. here and SomeService gets only instantiated once, with your App (considered you only instantiate your App once).

Repeat this with other Services you want to add to your App instance.

Some good articles on this, which are worth reading:

  1. http://www.potstuck.com/2009/01/08/php-dependency-injection/
  2. http://fabien.potencier.org/article/11/what-is-dependency-injection
0

精彩评论

暂无评论...
验证码 换一张
取 消