Jump to content

Problem with singletons


Jak

Recommended Posts

Hi,
I have a class that I’m using as a singleton and for some reason its just not working at all. Basically my A class (the singleton) is created, and the constructor creates a new B object (from the B class). The B class needs to use variables from the A classes instance, so its constructor calls the instance of A, but then it all goes wrong.

When the instance of A is called for the second time it still thinks it doesent exist (the if is true) and so creates another instance of A, therefore running the constructor again, which in turn creates B again and so on (it gets stuck in a loop). I have no idea why this is, has anyone got any ideas? Here is an example piece of code that demonstrates the problem (although here it actually returns an Internal Server Error rather than getting stuck in a loop):

[code]<?php

class A
{
static public function instance()
{
static $instance;
if(!isset($instance)) $instance = new A();
return $instance;
}

public function __construct()
{
new B;
}
}

class B
{
public function __construct()
{
A::instance();
}
}

A::instance();

?>[/code]

Thanks in advance,
Jack

Link to comment
Share on other sites

Hmm, i dont get that, i just get Internal Server Error. Anyway, line 5 is "static public function instance()" i dont see anything wrong with that, is there? Im pretty sure there's no syntax error, because if i remove the "A::instance();" line inside class B its all fine.

Im on PHP 5.2 by the way.
Link to comment
Share on other sites

Sorry.. I forgot which version of PHP I was using :)

Well, here with php 5.1.4 it gives me a segmentation fault.  That's pretty bad.  I altered the code to this:

[code=php:0]<?php

        class A
        {
                static public function instance()
                {
                        static $instance;
                        if(!isset($instance)) {
                          print "Created instance\n";
                          $instance = new A();
                        } else {
                          print "Didn't create instance\n";
                        }
                        return $instance;
                }

                public function __construct()
                {
                        new B;
                }
        }

        class B
        {
                public function __construct()
                {
                        A::instance();
                }
        }

        print "About to call A::instance()\n";
        A::instance();

?>[/code]


The output is:

About to call A::instance()
Created instance
Created instance
....
Segmentation fault

Edit:  Oops.. I should have put the print earlier.  Yes, it is looping.



Link to comment
Share on other sites

Hmm, i dont really understand. I thought the whole point of the singleton pattern was that only one instance of the class should exist, so surley the "but once per every object" thing shouldnt matter, because there should only be one.

Every example of a singleton in php ive seen has created it like this (or similar), yet it dosent seem to work. Im sure it has something to do with that fact that the class getting the instance a second time is being created by the instance the first time. If i do this:

[code]<?php

class A
{
public static function instance()
{
static $instance;
if(!isset($instance)) $instance = new A();
return $instance;
}

public function __construct()
{
new B;
}
}

class B
{
public function __construct()
{
//A::instance();
}
}

$c = A::instance();
$c->test = 1;
$d = A::instance();
echo $d->test;

?>[/code]

It returns 1, as expected, so the singleton is working, just not when it is a child of something else. Is there any way to fix it, or is it a bug in PHP?
Link to comment
Share on other sites

Hey, someone helped me figure it out, for anyone thats interested, its because the first instance of A dosent exist until the constructor has finished running, and because B is created within the constructor when B tries to call the instance of A it dosent exist yet, and so it goes round and round.
Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.