[PHP] Re: Singletons
Hi, here is in my opinion, what you can do: class Base { private $foo; private function __construct() {} public function getFoo() { return $this-foo; } public function setFoo( $foo ) { $this-foo = $foo; } } class Singleton extends Base { public function __construct() {} private function __clone() {} public static function getInstance() { static $instance = null; if (!isset($instance)) $instance = new self(); $instance-setFoo( 'singleton' ); return $instance; } } $bar = Singleton::getInstance(); echo $bar-getFoo(); // Singleton Regards Carlos -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
[PHP] Re: Singletons
Colin Guthrie schrieb: Stut wrote: On 20 Oct 2008, at 20:24, Christoph Boget wrote: public function __construct() A singleton would usually have a private constructor to prevent non-singleton instances. The problem being if the class in question derives from another class that has a public constructor... If you are in that particular situation (which I am), you're basically SOL and the statement above has no bearing. Correct, but you're then breaking one of the rules of the singleton pattern. If you're stuck with that then you'll need to enforce the singleton aspect in non-technical ways (policy, regular beatings, etc). I disagree (not with the regular beatings... that's very important for moral!), but with the statement that says you are SOL if you want to create a singleton that derives from another class with a public constructor, you just have to make the derived class' constructor private and call the parent's constructor: class Base { private $foo; public function __construct($foo) { $this-foo = $foo; } public function getFoo() { return $this-foo; } } class Singleton extends Base { private function __construct() { parent::__construct(Singleton); } public static function getInstance() { static $instance = null; if (!isset($instance)) $instance = new self(); return $instance; } } $bar = Singleton::getInstance(); $bar-getFoo(); // Singleton (entirely untested) Col Hallo, this is the Result of my test with your Code: Fatal error: Access level to Singleton::__construct() must be public (as in class Base) in C:\Users\cmedina\Documents\test1.php on line 30 Regards Carlos -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
[PHP] Re: Singletons
Stut wrote: On 20 Oct 2008, at 20:24, Christoph Boget wrote: public function __construct() A singleton would usually have a private constructor to prevent non-singleton instances. The problem being if the class in question derives from another class that has a public constructor... If you are in that particular situation (which I am), you're basically SOL and the statement above has no bearing. Correct, but you're then breaking one of the rules of the singleton pattern. If you're stuck with that then you'll need to enforce the singleton aspect in non-technical ways (policy, regular beatings, etc). I disagree (not with the regular beatings... that's very important for moral!), but with the statement that says you are SOL if you want to create a singleton that derives from another class with a public constructor, you just have to make the derived class' constructor private and call the parent's constructor: class Base { private $foo; public function __construct($foo) { $this-foo = $foo; } public function getFoo() { return $this-foo; } } class Singleton extends Base { private function __construct() { parent::__construct(Singleton); } public static function getInstance() { static $instance = null; if (!isset($instance)) $instance = new self(); return $instance; } } $bar = Singleton::getInstance(); $bar-getFoo(); // Singleton (entirely untested) Col -- Colin Guthrie gmane(at)colin.guthr.ie http://colin.guthr.ie/ Day Job: Tribalogic Limited [http://www.tribalogic.net/] Open Source: Mandriva Linux Contributor [http://www.mandriva.com/] PulseAudio Hacker [http://www.pulseaudio.org/] Trac Hacker [http://trac.edgewall.org/] -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP] Re: Singletons
here is in my opinion, what you can do: class Base { private function __construct() Except that in one of my follow up posts I indicated that my singleton class was deriving from a class that had a public constructor. Thanks anyway. I ended up just using Stut's suggestion. As he said, it's not pretty but it is simple. thnx, Christoph -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
[PHP] Re: Singletons
Carlos Medina wrote: this is the Result of my test with your Code: Fatal error: Access level to Singleton::__construct() must be public (as in class Base) in C:\Users\cmedina\Documents\test1.php on line 30 Hmmm, that'll learn me for not running it first I sps :s Well that is completely crap. I didn't realise there was such a limitation in PHP's object heirarchy. Wonder why it's like this... Can't think of a valid reason... Col -- Colin Guthrie gmane(at)colin.guthr.ie http://colin.guthr.ie/ Day Job: Tribalogic Limited [http://www.tribalogic.net/] Open Source: Mandriva Linux Contributor [http://www.mandriva.com/] PulseAudio Hacker [http://www.pulseaudio.org/] Trac Hacker [http://trac.edgewall.org/] -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
[PHP] Re: Singletons
Christoph Boget wrote: Ok, so why isn't this working as (I, at the very least) expected? class singleTon { private static $thisObj = NULL; private $thisProp = NULL; public function __construct() { echo 'singleTon::__construct()br'; if( !is_null( singleTon::$thisObj )) { echo '$thisObj already set. returning it...br'; return singleTon::$thisObj; } singleTon::$thisObj = $this; } public static function singleton() { echo 'singleTon::singleton()br'; if( is_null( singleTon::$thisObj )) { $retval = new singleTon(); } return singleTon::$thisObj; } public function setThisProp( $sVal ) { $this-thisProp = $sVal; } public function getThisProp() { return $this-thisProp; } } $one = singleTon::singleton(); $one-setThisProp( 'Joe' ); echo '$one-getThisProp();: [' . $one-getThisProp() . ']br'; echo '$one: [pre' . var_export( $one, TRUE ) . '/pre]br'; $two = new singleTon(); echo '$two-getThisProp();: [' . $two-getThisProp() . ']br'; $two-setThisProp( 'Bob' ); echo '$two: [pre' . var_export( $two, TRUE ) . '/pre]br'; echo '$one-getThisProp();: [' . $one-getThisProp() . ']br'; echo '$two-getThisProp();: [' . $two-getThisProp() . ']br'; echo '$one-getThisProp();: [' . $one-getThisProp() . ']br'; I would have thought that both $one and $two would be referencing the same object but they aren't. Apart from making the constructor private, is there any way I can ensure that there is ever only one instance of an object? thnx, Christoph you can't return from a constructor; thus always use the static singleton method() i.e.: $two = singleTon::singleton(); -- nathan ( [EMAIL PROTECTED] ) { Senior Web Developer php + java + flex + xmpp + xml + ecmascript web development edinburgh | http://kraya.co.uk/ } -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php