note 82617 added to language.oop5.patterns
| From: | Chris at osu1 dot php dot net | Date: | Fri, 18 Apr 2008 14:11:46 +0000 |
| Subject: | note 82617 added to language.oop5.patterns | ||
| Groups: | php.notes | ||
| Request: | Send a blank email to php-notes+get-138479@lists.php.net to get a copy of this message | ||
This is an extension to Mattlock's Singleton class and interface.
It has a number of advantages:
1) It uses a single abstract class instead of an interface and class definition, which to me is
cleaner.
2) It allows for multiple instances of one class where you only wish to have one of any instance
initialised with certain arguments. For example a File class representing a file on the system,
there will be multiple files, but you will only want one instance of the File class for each
individual file.
but a number of disadvantages:
1) The use of ReflectionClass is far from ideal, but I cannot find a better way to initialise an
"unknown" class with arguments to the constructor, without requiring another
'utility' method in the child class.
2) The __construct method of child classes MUST be declared 'public' so that the
ReflectionClass can instantiate it.
if there is a good way to instantiate a class in a function that has its name as a string and an
array holding its arguments, without using eval etc, please tell me :D
<?php
abstract class Singleton
{
static abstract public function getInstance();
static final protected function getClassInstance($klass)
{
// Initialize array for $instances
if(self::$instances === NULL)
self::$instances = array();
// Get arguments and remove $klass
$args = func_get_args();
array_shift($args);
// Create key from args
$key = serialize($args);
// Initialize array for instances of $klass
if(!array_key_exists($klass, self::$instances))
self::$instances[$klass] = array();
// Instantiate $klass using reflection and store under $key
if(!array_key_exists($key, self::$instances[$klass]))
{
if(count($args) > 0)
{
$reflect = new ReflectionClass($klass);
self::$instances[$klass][$key] = $reflect->newInstanceArgs($args);
}
else
{
// ReflectionClass cannot pass arguments to classes with no constructor.
self::$instances[$klass][$key] = new $klass();
}
}
// Return instance of $klass
return self::$instances[$klass][$key];
}
static private
// Storage for all instances of Singleton classes
$instances;
}
class MySingleton extends Singleton
{
static public function getInstance()
{
return Singleton::getClassInstance(__CLASS__);
}
}
class ArgSingleton extends Singleton
{
public
$arg;
// Default arguments here NOT constuctor to prevent dupilicate instances.
static public function getInstance($arg = 'Default')
{
return Singleton::getClassInstance(__CLASS__, $arg);
}
public function __construct($arg)
{
$this->arg = $arg;
}
}
echo '<pre>';
$a = MySingleton::getInstance();
$b = MySingleton::getInstance();
var_dump($a);
var_dump($b);
$c = ArgSingleton::getInstance();
$d = ArgSingleton::getInstance('Default');
$e = ArgSingleton::getInstance('Default');
var_dump($c);
var_dump($d);
var_dump($e);
echo '</pre>';
?>
----
Server IP: 87.124.64.96
Probable Submitter: 81.158.173.187
----
Manual Page -- http://www.php.net/manual/en/language.oop5.patterns.php
Edit -- https://master.php.net/note/edit/82617
Del: integrated -- https://master.php.net/note/delete/82617/integrated
Del: useless -- https://master.php.net/note/delete/82617/useless
Del: bad code -- https://master.php.net/note/delete/82617/bad+code
Del: spam -- https://master.php.net/note/delete/82617/spam
Del: non-english -- https://master.php.net/note/delete/82617/non-english
Del: in docs -- https://master.php.net/note/delete/82617/in+docs
Del: other reasons-- https://master.php.net/note/delete/82617
Reject -- https://master.php.net/note/reject/82617
Search -- https://master.php.net/manage/user-notes.php