Re: OO and "Singleton" class

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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@xxxxxxxxx> wrote:
> On Tue, Sep 1, 2009 at 5:16 PM, Paul M Foster<paulf@xxxxxxxxxxxxxxxxx> 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@xxxxxxxxxxxx : http://techstyle.jp/
    koyama@xxxxxxxx : http://d.hatena.ne.jp/koyhoge/

-- 
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php


[Index of Archives]     [PHP Home]     [Apache Users]     [PHP on Windows]     [Kernel Newbies]     [PHP Install]     [PHP Classes]     [Pear]     [Postgresql]     [Postgresql PHP]     [PHP on Windows]     [PHP Database Programming]     [PHP SOAP]

  Powered by Linux