Re: OO and "Singleton" class
| From: | KOYAMA Tetsuji | Date: | Wed, 02 Sep 2009 05:02:25 +0000 |
| Subject: | Re: OO and "Singleton" class | ||
| References: | 1 2 | Groups: | php.general |
| Request: | Send a blank email to php-general+get-297597@lists.php.net to get a copy of this message | ||
Hi,
After PHP 5.3, there is better implements for Singleton.
http://d.hatena.ne.jp/Yudoufu/20090811/1250021010
This entry was written by Japanese, but you may understand php code. :-)
On Wed, Sep 2, 2009 at 07:06, Eddie Drapkin<oorza2k5@gmail.com> wrote:
> On Tue, Sep 1, 2009 at 5:16 PM, Paul M Foster<paulf@quillandmouse.com> wrote:
>>
>> I'm a little fuzzy on some of the PHP implementation details for some
>> stuff. In PHP (5 <= phpversion() < 5.3), I'd like a configuration class
>> which can only effectively be instantiated once. Will the following code
>> do this? Any other suggestions or corrections? (Code is untested. Feel
>> free to complain about syntax.)
>>
>> class config
>> {
>> private static $cfg;
>>
>> // Initializes the configuration from main config file
>> function __construct()
>> {
>> if (!is_array(self::$cfg)) {
>> if (defined('CFGFILE')) {
>> include(CFGFILE);
>> self::$cfg = $config;
>> }
>> else
>> self::$cfg = array();
>> }
>> }
>>
>> // Returns a config item or null if not found
>> function item($index)
>> {
>> if (array_key_exists($index, self::$cfg))
>> return self::$cfg[$index];
>> else
>> return null;
>> }
>>
>> // Sets a config item, optionally overwriting.
>> // Returns true on success, false on failure.
>> function set($index, $value, $overwrite = true)
>> {
>> $write = false;
>> if (array_key_exists($index, self::$cfg) and $overwrite)
>> $write = true;
>> elseif (!array_key_exists($index, self::$cfg))
>> $write = true;
>> if ($write) {
>> self::$cfg[$index] = $value;
>> return true;
>> }
>> else
>> return false;
>> }
>>
>> };
>>
>> Paul
>>
>> --
>> Paul M. Foster
>>
>> --
>> PHP General Mailing List (http://www.php.net/)
>> To unsubscribe, visit: http://www.php.net/unsub.php
>>
>>
>
> The primary thing you need to do to make a class a singleton is
> disallow the instantiation of a class directly. Which means using
> visibility, which is conspicuously absent from your example above.
>
> So, to prevent normal instantiation, we make the constructor private.
> Also, we need a method to retrieve the instance. Static members serve
> this purpose:
>
> class Singleton {
> private static $instance;
>
> private function __construct() { }
>
> public static function getInstance() {
> if( ! self::$instance instanceof Singleton) //replace Singleton
> with class name
> self::$instance = new Singleton; //replace Singleton with class name
>
> return self::$instance;
> }
>
> public function __clone() {
> throw new Exception('Cannot clone a Singleton');
> }
> }
>
> This class "shell" will prevent people from instantiating it ($foo =
> new Singleton is an error). Instead, deployment will look like `$foo
> = Singleton::getInstance()` which, as you can tell, always returns the
> same instance. Throwing an exception out of __clone() will prevent
> something like
$foo = Singleton::getInstance(); $bar = clone
> $foo;
> which is something I see overlooked a lot.
>
> So, if you wanted to convert your full class to a singleton it would
> look something like:
>
> class config {
> private static $instance;
> private static $cfg;
>
> private function __construct() {
> if(!is_array(self::$cfg)) {
> if(defined('CFGFILE')) {
> include(CFGFILE);
> self::$cfg = $config;
> } else {
> self::$cfg = array();
> }
> }
> }
>
> public function getInstance() {
> if(!(self::$instance instanceof config)) {
> self::$instance = new config();
> }
>
> return self::$instance;
> }
>
> public function __clone() {
> throw new Exception("Cannot clone a Singleton.");
> }
>
> public function item($index) {
> if(array_key_exists($index, self::$cfg))
> return self::$cfg[$index];
> else
> return null;
> }
>
> // Sets a config item, optionally overwriting.
> // Returns true on success, false on failure.
> function set($index, $value, $overwrite = true) {
> $write = false;
> if (array_key_exists($index, self::$cfg) and $overwrite) {
> $write = true;
> } elseif (!array_key_exists($index, self::$cfg)) {
> $write = true;
> }
>
> if ($write) {
> self::$cfg[$index] = $value;
> return true;
> } else {
> return false;
> }
> }
>
>
> }
>
> Note that this is also completely untested or anything of the sort.
>
> --
> PHP General Mailing List (http://www.php.net/)
> To unsubscribe, visit: http://www.php.net/unsub.php
>
>
--
小山哲志@テックスタイル
koyama@techstyle.jp : http://techstyle.jp/
koyama@hoge.org : http://d.hatena.ne.jp/koyhoge/