tags:

views:

34

answers:

2

Hello

I'm using the PHP singleton from Wikipedia. The problem is the singleton has a method that loads and runs other PHP scripts via require once and when these script are run and implement the Class method get_shared_instance a new singleton is initiated. Why is this? And what is the work around?

the singleton (in a basic form):

class Controller {

    protected static $shared_instance;

    public static function get_shared_instance()
    {
        if (self::$shared_instance === NULL) { 
            self::$shared_instance = new self();
        } 

        return self::$shared_instance;
    }

/// Constructor made private to be used with singleton.
final protected function __construct(){ $this->initiate(); }

/// Do not allow the clone operation: $x = clone $v;    
final protected function __clone() { }

the singleton's method that loads the other files

private function settings_by_domain()
{
    $current_domain = $_SERVER['HTTP_HOST'];
    $path = pathinfo(__FILE__, $options = PATHINFO_DIRNAME);
    $settings_file = $path.'/'.$current_domain.'.php';

    if (is_file($settings_file))
    {
        $this->settings_file = $settings_file;
        return TRUE;
    }
    else
    {
        return FALSE;
    }
}

The required file contain:

$c = self::get_shared_instance();

which, unfortunatly, when run creates a new instance?

Many thanks Ross

+1  A: 

It seems a circular dependency: the get_shared_instance() function calls the constructor, which calls initiate() which, in you case, calls settings_by_domain(). Inside the latter, get_shared_instance() is called again, but you are still inside the constructor, so that the static field $shared_instance is not yet instantiated.

Without all the code it is difficult to propose a solution, but I suggest you to check the reciprocal dependencies of the various classes and try and rationalize it. After all, why would a singleton depend upon a file that needs the singleton itself to work?

Iacopo
thanks. i'm running `initiate()`elsewhere. probably better. The singlton doesn't require anything else but goes looking for certain files. I hope that is justifiable in this situation.
Ross
A: 
class Controller {

protected static $shared_instance;

public static function get_shared_instance()
{
    if (self::$shared_instance === NULL) { 
    self::$shared_instance = new self();
} 

return self::$shared_instance;

}

a return in class scope? this is completely wrong. It should be:

class Controller {

protected static $shared_instance;

public static function get_shared_instance()
{
    if (self::$shared_instance === NULL) { 
    self::$shared_instance = new self();
    return self::$shared_instance;
} 

}

mhughes
if it returns from within the if statement, it won't return if the singleton has already been initiated?
Ross
damn sorry. the horrible indentation confused me.
mhughes
yeah sorry – my ugly formatting.
Ross