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