I am writing a custom PHP Application from scratch and for some classes I use the singleton pattern, because I need some information to be calculated one time and them I just use them.
Today I wrote a big part of my application and when I tested it all in all, it threw me the following error:
Maximum function nesting level of '100' reached, aborting.
I did some tests and found that error is generated by something like this:
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();
class Bar
{
public function doSomething()
{
F()->showSomeInformation();
}
}
To my mind it is valid because F()
was called before and it should have the instance of Foo in the static variable, and I believe it should somehow work, but it doesn't.
I feel lost now. How can I make it to work or at least how can I change something to have similar behavior?
The $instance
value remains null
all the time. Why? Well have a look what happens before you assign the instance to $instance
.
Before $instance
has any different value you call $bar->doSomething();
again.
This means you run F()
again but $instance
is still null
. Now you instantiate Foo
again but guess what $instance
is still null.
Try this:
<?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();
If you use the singleton pattern, make sure the class itself keeps track of whether it got initialized or not. Letting an external source handle this can cause a lot of problems (as you just experienced).