[英]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.