Page 1 of 1
Semi Singleton
Posted: Sat Aug 19, 2006 11:10 am
by Benjamin
How can I make a class that populates a variable with the first instance of itself? I want to be able to call the class so that I can retrieve the first instantiated instance..
Code: Select all
class whatsupyo {
private static $instance = false;
function __construct() {
if ($instance === false) {
$instance = ?
}
}
function get_instance() {
return $instance;
}
Posted: Sat Aug 19, 2006 11:18 am
by feyd
There's something fishy with doing this but..
Code: Select all
class foo
{
private static $instance = null;
public function __construct()
{
if (self::$instance === null)
{
self::$instance = $this;
}
else
{
throw new SingletonException();
}
}
public static function GetInstance()
{
if (self::$instance === null)
{
$class = __CLASS__;
new $class();
}
return self::$instance;
}
}
edit: possible logic fix.
Posted: Sat Aug 19, 2006 11:22 am
by Jenk
Why not lazy load the in the getInstance method instead?
That way, no matter what calls it first, aslong as they call the getInstance method you'll always have a singleton?
in other words, I don't see what this will achieve.
Posted: Sat Aug 19, 2006 11:40 am
by Benjamin
I don't want it to be a singleton, but I want to be able to retrieve the first instance without using a registry or global variable. Hence I figured this would work. Works great using $this.
Posted: Sat Aug 19, 2006 11:41 am
by feyd
astions wrote:I want to be able to retrieve the first instance without using a registry or global variable.
That's the general definition of a singleton.
Posted: Sat Aug 19, 2006 11:45 am
by Benjamin
I also need to be able to instantiate new instances of it, although, come to think of it, maybe it would be better to make copies of it.
Posted: Sat Aug 19, 2006 11:58 am
by feyd
I don't like the concept, but this is what you are looking for.
Code: Select all
class foo
{
private static $instance = null;
protected $bar;
public function __construct()
{
if (self::$instance === null)
{
self::$instance = $this;
}
$this->bar = mt_rand(1,100);
}
public static function GetFirstInstance()
{
if (self::$instance === null)
{
$class = new ReflectionClass(__CLASS__);
$class->newInstance();
}
return self::$instance;
}
}
$foo1 = new foo();
$foo2 = new foo();
$foo3 = foo::GetFirstInstance();
var_dump($foo1 === $foo2, $foo2 === $foo3, $foo1 === $foo3, $foo1, $foo2, $foo3);
Posted: Sat Aug 19, 2006 12:05 pm
by Benjamin
feyd, I was in the process of posting this while you posted your example. I'll use your example, but can you tell me why this doesn't work?
Code: Select all
class test {
private static $instance = false;
function __construct() {
if (self::$instance === false) {
self::$instance = $this;
}
}
public static function getInstance(){
return self::$instance;
}
}
$activate = new test();
// and I try to get the instance with..
$test = test::getInstance();
Posted: Sat Aug 19, 2006 12:14 pm
by feyd
It appears to work for me.
Posted: Sat Aug 19, 2006 1:30 pm
by Chris Corbyn
I don't understand the reason for putting the singleton logic in the constructor. Eeven if you had that same logic in the factory method for it you'd essentially have the same thing.
~astions, have you looked at using a registry? That would give you far more flexibility and allow to store mutliple instances if you wanted to, whilst still be able to refer to an instance over and over like a singleton without needing to pass it from object to object at each step.
Posted: Sat Aug 19, 2006 2:05 pm
by Benjamin
It's in the constructor to ensure that the first instance is captured.
As far as a registry is concerned, I've considered that, but with this method, which might just very well be a new pattern, I avoid using a registry, I can get an instance of the class from any other class without using globals, and I can still create a new instance if I need to.
Posted: Sat Aug 19, 2006 2:40 pm
by Chris Corbyn
astions wrote:I can get an instance of the class from any other class without using globals, and I can still create a new instance if I need to.
I'd change your singleton factory to this:
Code: Select all
public static function getInstance(){
if (self::$instance === null) self::$instance = new test();
return self::$instance;
}
Otherwise, how can you be sure you'll return a singleton? For your code to work you need to already have a live instance before the singleton will be returned

Posted: Sat Aug 19, 2006 2:42 pm
by Benjamin
Yeah I was going to do that, Thanks for the good example though, now I can just plug it in
