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