繁体   English   中英

PHP Singleton:达到最大功能嵌套级别“ 100”,正在中止

[英]PHP Singleton : Maximum function nesting level of '100' reached, aborting

我从头开始编写自定义PHP应用程序,对于某些类,我使用singleton模式,因为我需要一次计算一些信息,而我只使用它们。 今天,我写了我的应用程序的很大一部分,当我全部进行测试时,它引发了以下错误:达到最大功能嵌套级别'100',正在中止 我做了一些测试,发现错误是由这样的东西产生的:

的index.php

class Foo
{
    public function __construct()
    {
        if(!class_exists('Bar', false))
        {
            require 'Bar.php';
        }

        $bar = new Bar;
        $bar->doSomething();
    }

    public function showSomeInformation()
    {
        // information
    }
}

function F()
{
    static $instance = null;

    if(is_null($instance))
    {
        $instance = new Foo;
    }

    return $instance;
}

F();

Bar.php

class Bar
{
    public function doSomething()
    {
        F()->showSomeInformation();
    }
}

在我看来,这是有效的,因为F()是在之前调用的,并且它应该在静态变量中具有Foo的实例,而且我认为它应该以某种方式起作用,但事实并非如此。

我现在感到迷茫。 如何使其工作或至少如何改变某些东西以使其具有相似的行为?

好的,我已经在评论中提到了它,但是您可以继续。

$instance值始终保持为null 为什么? 在将实例分配给$instance之前,先看看会发生什么。

$instance具有任何其他值之前,请调用$bar->doSomething(); 再次。

这意味着您再次运行F() ,但$instance仍然为null 现在,您再次实例化Foo ,但是猜$instance仍然为空。

编辑:试试这个:

<?php class Foo
{
    static $instance = null;

    public function __construct()
    {
        if(!class_exists('Bar', false))
        {
            require 'Bar.php';
        }

        self::$instance = $this;

        $bar = new Bar;
        $bar->doSomething(self::$instance);
    }

    public function showSomeInformation()
    {
        // information
    }
}

class Bar
{
    public function doSomething($instance)
    {
        F($instance)->showSomeInformation();
    }
}

function F($instance = null)
{
    if(is_null($instance))
    {
        $instance = new Foo;
    }

    return $instance;
}

F();

如果您使用单例模式,请确保该类本身跟踪是否已初始化。 让外部源处理此问题可能会导致很多问题(就像您刚刚遇到的那样)。

无限递归发生在foo的构造函数中:

  function F()
  {
    static $instance = null;

    if(is_null($instance))
    {
        $instance = new Foo;
          echo("Never reached\n");
          if( is_null($instance) )
          {
                  echo("Still null!\n");
          }
      }

      return $instance;
  }

第一个F(); 调用不会创建Foo,它将调用Foo的构造函数,该构造函数将在返回Foo对象之前调用F(),但是F()调用另一个Foo的构造函数,它将永远做同样的事情,因此没有新的Foo将从F()返回,因此我们用完了堆栈。

这是PHP中合理的单例模式的示例。 http://www.phptherightway.com/pages/Design-Patterns.html

我不喜欢Singleton模式,我想,如果您有一点经验并开始进行单元测试,您也会讨厌它。 但是该模式无法像您尝试过的那样工作。

class MySingletonClass 
{
    private static $instance;

    //make constructor protected, to prevent direct instantiation
    protected function __construct() {}

    /**
    * @return MySingletonClass
    */
    public static function getInstance()
    {
         if (!self::$instance) {
             self::$instance = new self(); //new static() would we valid too, relevant for extending (late state binding)
         }
         return self::$instance;
    }

    public function getSomething() 
    {
         if (!$this->calculated) {
             $this->calculated = $this->calculateSomething();
         }
         return $this->calculated;
    }
}

echo MySingletonClass::getInstance()->getSomething();

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM