PHP Doku:: Pattern - language.oop5.patterns.html

Verlauf / Chronik / History: (1) anzeigen

Sie sind hier:
Doku-StartseitePHP-HandbuchSprachreferenzKlassen und ObjektePattern

Ein Service von Reinhard Neidl - Webprogrammierung.

Klassen und Objekte

<<Objektiteration

Magische Methoden>>

Pattern

Pattern sind eine Möglichkeit, um optimale Verfahren und gute Entwürfe zu beschreiben. Sie zeigen eine flexible Lösung für verbreitete Programierprobleme.

Factory

Das Factory-Pattern erlaubt die Instanziierung von Objekten zur Laufzeit. Es wird Factory-Pattern genannt, weil es für die "Herstellung" eines Objektes zuständig ist. Eine parametrisierte Factory bekommt den Namen der zu instanziierenden Klasse als Parameter übergeben.

Beispiel #1 Parametrisierte Factory-Methode

<?php
class Example
{
    
// Die parametrisierte Factory-Methode
    
public static function factory($type)
    {
        if (include_once 
'Drivers/' $type '.php') {
            
$classname 'Driver_' $type;
            return new 
$classname;
        } else {
            throw new 
Exception('Treiber nicht gefunden');
        }
    }
}
?>

Wenn diese Methode in einer Klasse definiert wird, erlaubt sie dieser, Treiber bei Bedarf zu laden. Wenn die Example-Klasse eine Datenbankabstraktionsklasse wäre, könnte das Laden eines MySQL- und SQLite-Treibers wie folgt aussehen:

<?php
// Lade einen MySQL Treiber
$mysql Example::factory('MySQL');

// Lade einen SQLite Treiber
$sqlite Example::factory('SQLite');
?>

Singleton

Das Singleton-Pattern greift in Situationen, in denen es nur eine Instanz einer Klasse geben darf. Das gebräuchlichste Beispiel ist eine Datenbankverbindung. Die Implementierung dieses Musters erlaubt dem Programmierer diese einzige Instanz leicht für viele andere Objekte zugänglich zu machen.

Beispiel #2 Singleton-Funktion

<?php
class Beispiel
{
    
// Speichert die Instanz der Klasse
    
private static $instance;
    
    
// Ein private-Konstruktor; verhindert die direkte Erzeugung des Objektes
    
private function __construct() 
    {
        echo 
'Ich bin hergestellt';
    }

    
// Die Singleton-Methode
    
public static function singleton() 
    {
        if (!isset(
self::$instance)) {
            
$c __CLASS__;
            
self::$instance = new $c;
        }

        return 
self::$instance;
    }
    
    
// Beispielmethode
    
public function bellen()
    {
        echo 
'Wuff!';
    }

    
// Halte Benutzer vom Klonen der Instanz ab
    
public function __clone()
    {
        
trigger_error('Klonen ist nicht erlaubt.'E_USER_ERROR);
    }

}

?>

Dies erlaubt das Abrufen einer einzigen Instanz der Example-Klasse.

<?php
// Dies wird fehlschlagen, weil der Konstruktor private ist
$test = new Example

// Dies wird immer eine einzige Instanz der Klasse abrufen
$test Example::singleton();
$test->bellen();

// Dies wird einen E_USER_ERROR erzeugen
$test_clone = clone $test;

?>

73 BenutzerBeiträge:
- Beiträge aktualisieren...
boukeversteegh at gmail dot com
18.08.2010 11:05
I've come up with an interesting and intuitive way to define a generic Factory class. It's basically an empty object that remembers all operations you perform on it. You can then request an actual instance, and all operations are repeated on that instance. The order of the operations is preserved.

<?php
   
# If you want a factory that initializes an object like this:
   
$myobject = new MyObject('arg1', 'arg2');
   
$myobject->doFooBar();
   
$myobject->baz = 10;
   
   
# You write:
   
$f_myobject = new MagicFactory('MyObject', 'arg1', 'arg2');
   
$f_myobject->doFooBar();
   
$f_myobject->baz = 10;

   
# You can now get the same object like this:
   
$myobject = $f_myobject->instance();
?>

<?php
   
   
/**
     * Generic Factory class
     *
     * This Magic Factory will remember all operations you perform on it,
     * and apply them to the object it instantiates.
     *
     */
   
class MagicFactory {
        private
$history, $class, $constructor_args;
       
       
/**
         * Create a factory of given class. Accepts extra arguments to be passed to
         * class constructor.
         */
       
function __construct( $class ) {
           
$args = func_get_args();
           
$this->class = $class;
           
$this->constructor_args = array_slice( $args, 1 );
        }
       
        function
__call( $method, $args ) {
           
$this->history[] = Array(
               
'action'    => 'call',
               
'method'    => $method,
               
'args'        => $args
           
);
        }
       
        function
__set( $property, $value ) {
           
$this->history[] = Array(
               
'action'    => 'set',
               
'property'    => $property,
               
'value'        => $value
           
);
        }
       
       
/**
         * Creates an instance and performs all operations that were done on this MagicFactory
         */
       
function instance() {
           
# use Reflection to create a new instance, using the $args
           
$reflection_object = new ReflectionClass( $this->class );
           
$object = $reflection_object->newInstanceArgs( $this->constructor_args );
           
           
# Alternative method that doesn't use ReflectionClass, but doesn't support variable
            # number of constructor parameters.
            //$object = new $this->class();
           
            # Repeat all remembered operations, apply to new object.
           
foreach( $this->history as $item ) {
                if(
$item['action'] == 'call' ) {
                   
call_user_func_array( Array( $object, $item['method'] ), $item['args'] );
                }
                if(
$item['action'] == 'set' ) {
                   
$object->{$item['property']} = $item['value'];
                }
            }
           
           
# Done
           
return $object;
        }
    }
   
?>

Example:

<?php
   
   
class Person {
        private
$name, $sirname;
        public
$age;
       
        function
__construct( $name, $sirname ) {
           
$this->name = $name;
           
$this->sirname = $sirname;
        }
       
        function
setName( $name ) {
           
$this->name = $name;
        }
       
        function
introduce() {
            print
"Hello, my name is {$this->name} {$this->sirname}! I'm {$this->age} years old.";
        }
    }
   
   
# Setup a factory
   
$person_factory = new MagicFactory('Person', 'John', 'Johnson');
   
$person_factory->setName('Jack');
   
$person_factory->age = 55;
   
   
# Get an instance
   
$jack = $person_factory->instance();
   
$jack->introduce();
   
   
# Prints:
    # Hello, my name is Jack Johnson! I'm 55 years old
Anonymous
10.06.2010 14:39
Singleton in php doesn't responded like java (or others), the static instance resets on every request......
Deman
5.03.2010 16:11
Php needs macros! That's right php seems almost unusable sometimes without precompiler. Fortunately you can generate php code with php and (easily) cache it so you can still take advantage of the php optimizing capabilities. It just creates a mess when debugging, no big deal ;)

You need to extend the language to your own needs.

But this singleton business might just work without without macros, not that nicely though.

<?php
class Singleton {
    private static
$instance;
    public static function
singleton($class = __CLASS__) {
        if (!isset(
self::$instance))
           
self::$instance = array();
        if (!isset(
self::$instance[$classname]))
           
self::$instance[$classname] = new $classname;
        return
self::$instance[$classname];
    }
}
class
SubClass extends Singleton {
    public static function
singleton($class = __CLASS__) {
        return
parent::singleton($class);
    }
}
class
SubSubClass extends SubClass {
    public static function
singleton($class = __CLASS__) {
        return
parent::singleton($class);
    }
}
?>

As you can see, the static $instance can be an associative array holding all the instances of derived classes, but you still can't work around overriding the singleton/getInstance static method... That's what macros or language extensions would be for...

<?php
class SINGLETON(SubClass) {
   
/*...*/
}
?>

Translate to:

<?php
class SubClass extends Singleton {
    public static function
singleton($class = __CLASS__) {
        return
parent::singleton($class);
    }
   
/*...*/
}
?>
quentinberlemont at gmail dot com
17.12.2009 18:01
<?php
/**
 * Class Singleton is a generic implementation of the singleton design pattern.
 *
 * Extending this class allows to make a single instance easily accessible by
 * many other objects.
 *
 * @author     Quentin Berlemont <quentinberlemont@gmail.com>
 */
abstract class Singleton
{
   
/**
     * Prevents direct creation of object.
     *
     * @param  void
     * @return void
     */
   
protected function __construct() {}

   
/**
     * Prevents to clone the instance.
     *
     * @param  void
     * @return void
     */
   
final private function __clone() {}

   
/**
     * Gets a single instance of the class the static method is called in.
     *
     * See the {@link http://php.net/lsb Late Static Bindings} feature for more
     * information.
     *
     * @param  void
     * @return object Returns a single instance of the class.
     */
   
final static public function getInstance()
    {
        static
$instance = null;

        return
$instance ?: $instance = new static;
    }
}
?>

E.g.

<?php
// Foo class
class Foo extends \Framework\Core\Singleton
{
   
// Bar method
   
public function bar()
    {
        echo
__CLASS__ . PHP_EOL;
    }
}

// Returns a single instance of Foo class
$foo = Foo::getInstance();

// Prints: Foo
 
$foo->bar();
?>

Best regards,
Quentin.
ltearno at gmail dot com
22.09.2009 18:11
The Singleton class version wich is useable by only extending it :

you would use is for example like this :

<?php
class Users extends Singleton
{
   
// ...
   
public function SomeMethod()
    {
    }
}
?>

and in your code :

<?php
Users
::inst()->SomeMethod();
?>

I didn't check for performance, but here is the code :

<?php
class Singleton
{
   
// Hold an instance of the class
   
private static $instances = array();
   
   
// A private constructor; prevents direct creation of object
   
final private function __construct()
    {
    }

   
// Prevent users to clone the instance
   
final public function __clone()
    {
       
trigger_error( 'Clone is not allowed.', E_USER_ERROR );
    }
   
   
// The singleton method
   
final public static function inst()
    {
       
$c = get_called_class();
       
        if( ! isset(
self::$instances[$c] ) )
        {
           
self::$instances[$c] = new $c;
        }
       
        return
self::$instances[$c];
    }
}
?>
edgar at goodforall dot eu
25.08.2009 11:03
Example, which shows how the class works:
<?php

/* First we create hunderd numbered chainable classes, which will quadrate the passed integer if the number of the class is the same as the integer.
*/
for($i = 0; $i < 100; $i++){
$funcs[] = create_function('','class C'.$i.' extends Chainable {
        public function run(Message $msg){

        $int = $msg->getMessage();
        if($int == '
.$i.'){
                return new Message($int * $int);

        }

        }
        };
        return new C'
.$i.';

        '
);
}
/* Then we create a function, which will chain the objects together and returns C0.
 C0 -> C1 -> C2 -> C3 ... -> C99
*/
function chain($funcs, $c = null){
        if(
$c == null){
               
$func = array_pop($funcs);
               
$c = $func();
               
$init = true;
        } else {
               
$init = false;
        }
        if(
count($funcs) > 0){
               
$func = array_pop($funcs);
               
$d = $func();
               
$c->addLink($d);
               
chain($funcs, $d);
        }
        if(
$init){
                return
$c;
        }
}
/* Create the chain */
$c = chain($funcs);

/* Now we can use the chain to calculate quadrates up to 99
output:
25
No object can handle this type
*/
try {
/* This will forward the new Message(5) to C0 then to C1 until it reaches C5,
which calculates 5 * 5 and then returns new Message(5 * 5) to C4 -> C3 .. ->C0 -> caller
When I enter 100 the chain will fail to process the integer, because there is no C100 class. C99 will throw an exception.
*/ 
       
$mesg = $c->forward(new Message(5)); // 25
       
print $mesg . "\n";
       
$mesg = $c->forward(new Message(100));
        print
$mesg . "\n";
} catch(
Exception $e) {
        print
$e->getMessage() . "\n";
}
?>
edgar at goodforall dot eu
24.08.2009 18:39
This class will let you chain objects together into a chain. You can forward a message into the chain. The message propagates upwards into the chain until an object can handle it and returns a value. Then the return value is send backwards into the chain until it reached the caller.

This can be useful in various situations, where flexibility is needed.

In the begin of the chain we put more specialized methods, which will handle special cases (like user defined objects, json code, xml etcetera). And in the back more general (strings, array's). Now we can pass data to the chain and always get valid and safe html back. If we encounter a new data type we just put on the head of the chain a new object, which can handle this type of data.

<?php

abstract class Chainable {
        protected
$next = null;
        protected
$prev = null;
        protected
$res = null;

        public function
forward(Message $object){
                if(
$return = $this->run($object)){
                        return
$this->backward($return);
                }
                if(
$this->next !== null){
                        return
$this->next->forward($object);
                } else {
                        throw new
Exception('No object can handle this type');
                }
        }
        public function
backward(Message $object){
        
                if(
$this->prev === null){
                        return
$object;
                } else {
                        return
$this->prev->backward($object);
                }
        }
        abstract public function
run(Message $object);
        public function
addLink(Chainable $link){
                if(
$this->next !== null){
                       
$this->next->addLink($link);
                } else {
                       
$this->next = $link;
                       
$this->next->setPrevLink($this);
                }
                return
$this;
        }
        protected function
setPrevLink(Chainable $link){
               
$this->prev = $link;
                return
$this;
        }
}
?>

Also needed the message object:

<?php
   
class Message {
        protected
$data;
        public function
__construct($data){
               
$this->data = $data;
        }
        public function
getMessage(){
                return
$this->data;
        }
        public function
setMessage($data){
               
$this->data = $data;
        }
        public function
__toString(){
                return (string)
$this->data;
        }
}

?>
edgar at goodforall dot eu
13.07.2009 17:48
Example of a decorator, which adds array access to any object:

<?php

class ArrayAccessDecorator implements ArrayAccess {
        protected
$object = null;
        public function
__construct($object){
               
$this->object = $object;
        }
        public function
__call($method, $args){
                return
$this->productpart->$method($args);
        }
        public function
__set($key, $val){
               
$this->object->$key = $val;
        }
        public function
__get($key){
                return
$this->object->$key;
        }
       
/* ArrayAccess */
       
public function offsetSet($key, $value){
               
$this->__set($key, $value);
        }
        public function
offsetGet($key){
                return
$this->__get($key);
        }
        public function
offsetUnset($key){
               
$this->__set($key, null);
        }
        public function
offsetExists($offset){

                       
$test = $this->object->__get($offset);
                        if(
$test !== null){
                                return
true;
                        } else {
                                return
false;
                        }
        }
}

$stdobject = (object)array('test'=>'test', 'test2' => 'test2');
$arr = new ArrayAccessDecorator($stdobject);
print
$arr['test']; // test
$arr['test'] = 'hello';
print
$arr['test']; // hello
?>
rskret at gmail dot com
5.06.2009 0:46
Ex.2 only makes a 'Singleton' in the sense there is only one object makable.
But! you can still assign the object to other names(like making aliases). Probably not
what you usually want. Change the method a bit and you get only one unique name
for your 'Singleton'.. or else it will bark again and again!
<?php
#if you don't change example 2 you will get a $badDoggie
$badDoggie="I am constructedSorry but I'm already set.Sorry but I'm already set.
            Sorry but I'm already set.Woof!Woof!Woof!"
;
   
// The singleton method
   
public static function singleton()
    {   
        if (!isset(
self::$instance)) {
           
$c = __CLASS__;
           
self::$instance = new $c;
           
#return self::$instance;
       
}
        echo
"Sorry but I'm already set.";
        return
self::$instance; ##...wrong place for this!comment this, uncomment it above
   
}   
?>
<?php
// This would fail because the constructor is private
#$test = new Example;
// This will always retrieve a single instance of the class
$test = Example::singleton();
$again = Example::singleton();
$and_again = Example::singleton();
$test->bark();
$again->bark();
$and_again->bark();
?>
marshall dot mattingly at NOSPAM dot gmail dot com
17.04.2009 18:56
Here's my singleton class for php 5.3.0:

<?php
class Singleton {
 
// this must be in every inherited singleton!
 
protected static $_instance;

 
// get the instance
 
final public static function instance() {
   
// create the instance if we don't have one
   
if (empty(static::$_instance)) {
     
$class = get_called_class(); // php 5.3.0
     
static::$_instance = new $class;
    }

    return static::
$_instance;
  }

 
// must protect the constructor
 
protected function __construct() { }

 
// overload __clone
 
final public function __clone() {
    throw new
Exception('Cannot duplicate a singleton.');
  }
}

// a sample extension
class Extension extends Singleton {
 
// has to be here, sadly... if only statics were inherited
 
protected static $_instance;

  protected function
__construct() { ... }

  public function
foo() {
    echo
'foo\n';
  }
}

// example
$extension = Extension::instance();
$extension->foo(); // echo's 'foo\n' as expected
?>

Having to add "protected static $_instance" to every singleton is somewhat annoying. I tried the obvious alternative and stored all the instances within an array in the Singleton class. I ran Extension::getInstance() 1,000,000 over 10 runs to see which method was faster:

Array of $_instances:  3.47s average
Individual $_instance: 1.75s average

Considering the array of instances only had 1 key to search through, it's reasonable to assume that method would get slower as singletons are added, whereas the method above will always stay the same speed. The difference was enough for me to suffer the minor inconvenience.
grummfy at gmail dot com
6.04.2009 18:23
Well, for non-php 5.3 users, another way is replacing get_called_class() by get_class(self) ou get_class($this).
grummfy at gmail dot com
6.04.2009 5:33
Exemple of singleton that can be used for other class (need phpversion >= 5.3)
<?php
class SingletonModel
{
   
/**
     * Instance of singleton's class
     *
     * @var array
     */
   
private static $_instance;

   
/**
     * All constructeur should be protected
     */
   
protected function __construct(){}

   
/**
     * Singleton method to load a new object
     *
     * @return HlPwd_SingletonModel
     */
   
public static function singleton()
    {
        if (!isset(
self::$instance[ get_called_class() ]))
        {
           
$c = get_called_class();
           
self::$instance = new $c;
        }
       
        return
self::$instance;
    }

   
/**
     * Destroy the singleton
     */
   
public function destroySingleton()
    {
        unset(
self::$_instance[ get_class($this) ]);
    }

   
/**
     * Destructeur
     */
   
public function __destruct()
    {
        unset(
self::$_instance);
    }

   
/**
     * Impeach the clone of singleton
     */
   
public function __clone()
    {
       
trigger_error('Cloning not allowed on a singleton object', E_USER_ERROR);
    }
}

# EOF

you can easyli use it  like that

class mySingChild extends SingletonModel
{
    protected function
__construct()
    {
       
//do important things
   
}

    public function
foo()
    {
        echo
'hello world';
    }
}

$t = mySingChild::singleton();
$t->foo();
Talraith
12.03.2009 17:42
Building on vaddsm(at)gmail.com's idea...

I think a simpler option is to have a loader class/object and then the actual class.  It keeps your class more secure in that you are defining the visibility on $instances and you keep your class neat and tidy.

I found this useful when trying to use the singleton method on a class that extends another class.

<?php

class module_loader {
    private static
$instances;

    public static function
getInstance($module_name) {
        if (!isset(
self::$instances[$module_name])) {
           
self::$instances[$module_name] = new $module_name();
        }

        return
self::$instances[$module_name];
    }
}

class
module_base {
   
proteced $name;

    public function
__construct() {
       
// Do initialization stuff here

   
}

    public final function
SomePermanentFunction() {
       
// Perform function actions
   
}
}

class
module_test extends module_base {
    public
$my_var;

    public function
__construct() {
       
parent::__construct();

       
$this->name = 'test';
       
$this->my_var = '';
    }

    public function
ModuleSpecificFunction() {

    }
}

?>

So then once you have all of that defined, you can then use it like such:

<?php

// Get first instance and set value
$instance1 = module_loader::getInstance('module_test');
$instance1->my_var = 'abc';

print
"Instance 1 Var = " . $instance1->my_var;

// Create second instance and check value
$instance2 = module_loader::getInstance('module_test');

print
"Instance 2 Var = " . $instance2->my_var;

// Set value on second instance, check first instance
$instance2->my_var = 'def';

print
"Instance 1 Var = " . $instance1->my_var;

?>

The output would then look like this:

Instance 1 Var = abc
Instance 2 Var = abc
Instance 1 Var = def

Thus $instance1 and $instance2 are created using the factory pattern but they both point back to the same object (singleton pattern).
vaddsm(at)gmail.com
22.01.2009 21:34
Hello! I want to suggest another fast and universal way to create a singleton, that can store instances any class types. The idea based on php's ability to create object's properties in run time, and magic functions support. Main trick is to create not existed property in __get method and assign to it a value of new instance of class, named as property.

Code:

<?php

class fClassOne
{

 public function
get()
 {
  return
"value 1<br>\n";
 }

 public function 
__construct()
 {
  echo
"fClassOne constructed<br>\n";
 }

}

class
fClassTwo
{

 public function
get()
 {
  return
"value 2<br>\n";
 }

 public function 
__construct()
 {
  echo
"fClassTwo constructed<br>\n";
 }

}

class
fSingleton
{
 public function
__get($sClassName)
 {
  echo
"isset check<br>\n";
  if(!isset(
$this->{$sClassName})) $this->{$sClassName} = new $sClassName;
  return
$this->{$sClassName};
 }
}

$MySingleton = new fSingleton();

for (
$i = 0; $i < 5; $i++) echo $MySingleton->fClassOne->get();

echo
$MySingleton->fClassTwo->get();
echo
$MySingleton->fClassTwo->get();

 
?>

Output:

isset check
fClassOne constructed
value 1
value 1
value 1
value 1
value 1
isset check
fClassTwo constructed
value 2
value 2
Anonymous
31.12.2008 20:34
nbcarts:

1: The singleton pattern ensures that only one instance of a class is ever created. Thus, applying it to a database connection object is common, since reusing a connection reduces latency and slows down reaching the database server's connection limit. If a database connection is only made in the singleton's constructor then it is probably impossible to accidentally open another connection via that object.

I say "probably impossible" because there are still some other issues: in this example, an invalid database connection identifier can be stored, retrieved, or lost (since it is an unserializable resource type) via object serialization without careful attention to the __sleep and __wakeup magic methods (and probably won't be valid on deserialization even if it is retained), and the __clone magic method should be implemented in a way that prevents object duplication.

(This example also ignores database connection pooling to stay focused on singletons.)

2: A singleton does not contain itself; it contains a reference to itself, which is conceptually similar to a pointer from the C language or a reference from Java. (In fact these are all very different under the hood and in practice, but I will ignore this for simplicity.)

Consider the following typical PHP 5.0 to 5.2 implementation:

<?php
class Example {
   
    private static
$instance;
   
    private
__construct() {
       
// Do important initializations here, like normal.
   
}
   
    public static function
getInstance() {
        if (
null == self::$instance):
           
// First invocation only.
           
$className = __CLASS__;
           
self::$instance = new $className();
        endif;
        return
self::$instance;
    }
   
    public function
__clone() {
        throw new
Exception('Illegally attempted to clone ' . __CLASS__);
    }
}
?>

Static class member variables can exist even without an instance of their class, and static class methods can be invoked without a class instance as well. The member variable that holds a reference to the singleton class instance ($instance) is static, as is the method to instantiate a singleton object (Example::getInstance()). Note that the variable $instance is private, so it cannot be affected by anything external to the class (thus preventing outside code from creating an instance of Example).

Static member variables are not really "inside" a class; each class instance points to the same static member variables as other instances, "sharing" these static variables between them (in a way) even before any class instances exist. Thus, Example::getInstance() always checks the same $instance variable.

3: The constructor has an access specifier of "private" to prevent direct instantiation using the "new" operator. (Prior to the implementation of the __callStatic features of PHP 5.3 it is not useful to mark the constructor "protected" since subclasses won't automatically also be singletons.) However, private methods can be invoked from a class's other methods; the static method Example::getInstance() is therefore allowed to invoke the private constructor. On first invocation, it creates an instance of Example and stores a reference to it in $instance. Subsequently, it just returns this reference.

4: The singleton pattern makes a class (slightly) more complicated, and the overhead of invoking its instantiation method is probably slightly higher than accessing a global variable instead. However, the benefits are substantial from an architectural perspective: it helps prevent performance losses due to accidentally instantiating more than one heavyweight class, it helps prevent bugs due to accidentally instantiating more than one instance of a class (such as a class that renders the requested HTML document in an online content management system), and helps keeps your global namespace and other lexical scopes clean even prior to the introduction of proper namespaces in PHP 5.3 (thus helping to prevent accidental variable clobbering or unexpected initial variable values from a previous module).
k at tamayuz dot com
13.10.2008 10:59
Till now writing singleton classes depends on making class constructor private or protected and that sounds good, but what if class constructor must be public (for example, a singleton class inherits from a non-singleton class which already has a public constructor). The way to do so is:

<?php
   
class nonSingleton
   
{
        protected
$_foo;
       
        public function
__construct($foo)
        {
           
$this -> _foo = $foo;
        }
    }
   
    class
Singleton extends nonSingleton
   
{
       
/**
         * Single instance of the class
         *
         * @var Singleton
         */
       
protected static $_instance = NULL;
       
/**
         * A flag to know if we are in getInstance method or not.
         *
         * @var bool
         */
       
protected static $_withinGetInstance = false;
       
       
/**
         * Public singleton class constructor
         *
         * @param mixed $foo
         */
       
public function __construct($foo)
        {
            if (!
self :: $_withinGetInstance)
                throw new
Exception('You cannot make a new instance of this class by using constructor, use getInstance() instead...');
           
parent :: __construct($foo);
           
/*
                Any other operations constructor should do...
            */
       
}
       
       
/**
         * Regular getInstance method
         *
         * @param mixed $foo
         * @return Singleton
         */
       
public static function getInstance($foo)
        {
           
self :: $_withinGetInstance = true;
            if (!
self :: $_instance)
               
self :: $_instance = new Singleton($foo);
           
self :: $_withinGetInstance = false;
            return
self :: $_instance;
        }
    }
?>
Anonymous
6.10.2008 11:38
The "red-neck singleton" presented by wbcarts is not a singleton, but a presentation of static class members.

Static members are shared by every instance of that class, and as such should work precisely as he describes using them.

Singleton pattern is used to ensure that there only ever exists one instance of the singleton class.
wbcarts at juno dot com
3.10.2008 23:49
"Red-Necked" SINGLETON STYLE

I'm not sure if this is a so-called "pattern" because I'm only using plain ol' static data - nuttin fancier than that. It seems to fit the singleton pattern you guys have been describing, but without private constructors, or references to itself. Here's my singleton class... after it's been country-fried!

<?php

class MutableSingletonModel {
  public static
$data1 = 1;
  public static
$data2 = 1;

  public static function
getInstance() {
    return new
MutableSingletonModel();
  }

  public function
getData1() {
    return
self::$data1;
  }

  public function
getData2() {
    return
self::$data2;
  }

  public function
setData1($value) {
    if(
$value > 0 && $value < 100) self::$data1 = $value;
  }

  public function
setData2($value) {
    if(
$value > 0 && $value < 100) self::$data2 = $value;
  }

  public function
__toString() {
    return
'MutableSingletonModel[data1=' . self::$data1 . ', data2=' . self::$data2 . ']';
  }
}

// try to set data before any objects is created
MutableSingletonModel::$data1 = 55;

$msm1 = MutableSingletonModel::getInstance();  // use the getInstance() method
$msm2 = new MutableSingletonModel();           // use the default constructor
$msm2->setData2(78);                           // set data with an instantiated object

echo $msm1 . '<br>';
echo
$msm2 . '<br>';
echo
MutableSingletonModel::getInstance() . '<br>';
echo (new
MutableSingletonModel());
?>
Each echo above writes: MutableSingletonModel[data1=55, data2=78]

... Now, I had a really hard time to crack the mystery of the private constructor. To me, any "data", "object", or "thing", of which there is only one, doesn't require "no way to construct it". Furthermore, how can an object (of which there is only one), contain another object of itself inside? Next time I buy a new Cadillac, I'm definitely gonna check the trunk for another!
Anonymous
30.09.2008 2:44
Let me describe another pattern it is called “Decorator”. It can be used to add features to already written object. It is useful for extending some library classes from your framework without changing the original classes (especially if somebody else wrote those). The actual meaning is best presented in an example.

<?php
// the main interface in which we going to do some decoration
interface salad{
    public function
wait();
}

// main class which is already defined and you can't or don't want to change
class shopSalad implements salad{
    private
$tomatoes;
    private
$cucumbers;
    private
$cheese;
   
    public function
__construct($tomatoes, $cucumbers, $cheese){
       
$this->tomatoes = $tomatoes;
       
$this->cucumbers = $cucumbers;
       
$this->cheese = $cheese;
    }
   
    public function
wait(){
        echo
"the salad is served using {$this->tomatoes} tomatoes, {$this->cucumbers} cucumbers and {$this->cheese} gr. of cheese.";
    }
}

// abstract decorator class - note that it implements salad
abstract class saladDecorator implements salad{
    protected
$salad// the object for decoration
   
public function __construct(salad $salad){
       
$this->salad=$salad;
    }
   
// there is no need to mention the wait function therefore this class inherits the original salad
    // the purpose of this class is maintaining the type of the object produced by the decorators.
    // it inherits the same interface as the original and it will be inherited by the concrete decorators
}

// sauce decorator
class saladSauce extends saladDecorator {
    public function
wait(){
       
$this->salad->wait();
        echo
" Then it was decorated with some sauce.";
       
    }
}

// onions decorator
class saladOnions extends saladDecorator {
    public function
wait(){
       
$this->salad->wait();
        echo
" Then it was decorated with some onions.";
    }
}

$order1 = new shopSalad(2,1,100); // creates the salad in the normal way
$order1 = new saladSauce($order1); // add a decorator to the class
$order1->wait();
echo
'<br />';

// or
$order3 = new saladOnions(new saladSauce(new shopSalad(1,0.5,50))); // you don't need to load a variable with the reference
$order3->wait();
?>

this will outputs:
the salad is served using 2 tomatoes, 1 cucumbers and 100 gr. of cheese. Then it was decorated with some sauce.
the salad is served using 3 tomatoes, 2 cucumbers and 100 gr. of cheese. Then it was decorated with some onions. Then it was decorated with some sauce.
the salad is served using 1 tomatoes, 0.5 cucumbers and 50 gr. of cheese. Then it was decorated with some souse. Then it was decorated with some onions.

The pattern is not intended to be used with simple object and I couldn't do more simple than that. The pattern is useful in every way when the extending of an object is required. It can be used to divide some methods from others or to create layers of interaction with the object. In example if you have an file interface and a imageFile class which implements the file and then you can have also an textFile for the textFile you can do some layering and if you want to read the file as XML you can mace a decorator to do so. The XML decorator will inherit the interface file so you can save it and    the instance of textFile will be given to create the decorator so you can read the actual text and pars it as XML. It is possible the file to be .ini or some other text based document and you can make a decorator for every one of them. This is the actual benefit of the pattern.
Partty
30.09.2008 1:13
The singleton effect you are applying to can be achieved in a old-fashioned and simpler way. Remember that the 'static' is the way for sharing the data between the objects from one type. And there is no pattern in this. So the only think you can do is to use the static keyword. If your program is already written and the rewrite is not recommended there is the "adapter pattern" witch can be used. It is intended to adapt an object to an already build environment. This is one way to have singleton functionality without actually the singleton pattern, it uses a class with static data and static methods and a adaptor class to adapt those methods to your interface.

The example shows how the every instance of the singlePoint class givs you the same data.
<?php
class single {
   
    static
$a;
    static
$b;
   
    protected static function
_start($a,$b){
       
self::$a=$a;
       
self::$b=$b;
    }
    protected static function
_get_a(){
        return
self::$a;
    }
    protected static function
_get_b(){
        return
self::$b;
    }
}
class
singlePoint extends single {
    public function
__construct($a='',$b=''){
        if(
$a!='' && $b!=''){
           
single::_start($a,$b);
        }
    }
    public function
get_a(){
        return
single::_get_a();
    }
    public function
get_b(){
        return
single::_get_b();
    }
}

class
scopeTest{
    public function
__construct(){
       
$singlePointInstance = new singlePoint();
        echo
'In scopeTest a='.$singlePointInstance->get_a().'<br />';
    }
}

$theSingle = new singlePoint(3,5);
echo
'In index a='.$theSingle->get_a().'<br />';

$theScopeTest = new scopeTest();
?>

My point is that you don't need single instance of the class but you need access to the same data over and over again ant the build in way to do that in every language I know so far is the 'static' keyword. It was engineered to give you this functionality. All the singleton patterns and even this adapter is unnecessary complication of the structure. KISS = “Keep It Simple Stupid” no need of that!
uacaman at gmail dot com
23.09.2008 20:47
In response to Partty:

Singleton is a very useful pattern, i guess you a missing the point.

Singleton is usefull to share a single instance of a class, lets say a config class among your application without strong coupling and thus making the code more easy to give maintenance in case of changes. Guess this is the whole point of OO.

Uacaman
Partty
20.09.2008 5:58
The singleton pattern is not verry userful. you can easely work around the problem in so many ways but it is not wort it.
When building an complex application you first have to desin a layer structure and if you do that well you do not need a singleton in any way.

btw the simplest way is to not use a instance of the class but only static methods and variables. there is no lost functionality and if you need this complexation so badly it's a good and fast solution.

<?php
class stat {
  public static
$any_data;

  private function
__construct(){} //locking the construction method

 
public static function func1($arg1){
   
self::$any_data=$arg1; // or more genius code
 
}
}

// the calling
stat::func1('Big data string to be writen in $any_data');
echo
stat::$any_data; //prints the string
?>

It is goot to point out that this is more error free way to do it, since you have the class name "stat" or the "self" word and then the var as it is deklared '$any_data' no dolar sign shifting.

and hear a more simple solution of the singleton problem: $GLOBALS['db']= new mysql();
and then use the object everywhere without woring for creating other instances. :) You benefin from the object's security and so on... and from the globality of the GLOBALS if the globals are forbiden you can use the $_SESSION instead, but remember that the objects aper ok in the session on the execution of the script the first time but the data will not be userful when you try to extract it from the session the second time you executing the script, unles you take some mesurs.
Mattlock
7.09.2008 3:49
I've been forward-developing for PHP 5.3, and couldn't help but notice that late-static-binding makes implementing Singletons simple. Its even easy to set up some function forwarding so that static calls are transformed into non-staic calls:

<?php
// Requires PHP 5.3!
class Singleton {
    public static function
Instance() {
        static
$instances = array();
       
$class = get_called_class();
        if (!
array_key_exists($class, $instances)) {
           
$instances[$class] = new $class();
        }
        return
$instances[$class];
    }
    public static function
__callStatic($func, $args) {
       
$class = static::Instance();
        return
call_user_func_array(array($class, '__'.$func), $args);
    }
}

class
Earth extends Singleton {
    public function
__DoSomething($a, $b) {
        return
15 + $this->SomethingElse($a, $b);
    }
    protected function
SomethingElse($c, $d) {
        return
$c % $d;
    }
}

echo
Earth::DoSomething(6,27);
?>
alexander gavazov
27.08.2008 16:05
For quick instance access use function
<?php
class Example{....}

function
Example {
  return
Example::getInstance();
}

// Global access
Example()->sayHallo(...);
Example()->doSomething(...);
print
Example()->someData;
?>
shenkong at php dot net
14.08.2008 4:44
Strategy:

<?php
interface FlyBehavior {
    public function
fly();
}
interface
QuackBehavior {
    public function
quack();
}
class
FlyWithWings implements FlyBehavior {
    public function
fly() {
        echo
"I'm flying!!\n";
    }
}
class
FlyNoWay implements FlyBehavior {
    public function
fly() {
        echo
"I can't fly!\n";
    }
}
class
FlyRocketPowered implements FlyBehavior {
    public function
fly() {
        echo
"I'm flying with a rocket!\n";
    }
}
class
Qquack implements QuackBehavior {
    public function
quack() {
        echo
"Quack\n";
    }
}
class
Squeak implements QuackBehavior {
    public function
quack() {
        echo
"Squeak\n";
    }
}
class
MuteQuack implements QuackBehavior {
    public function
quack() {
        echo
"<< Silence >>\n";
    }
}
abstract class
Duck {
    protected
$quack_obj;
    protected
$fly_obj;
    public abstract function
display();

    public function
performQuack() {
       
$this->quack_obj->quack();
    }
    public function
performFly() {
       
$this->fly_obj->fly();
    }
    public function
swim() {
        echo
"All ducks float, even decoys!\n";
    }
    public function
setFlyBehavior(FlyBehavior $fb) {
       
$this->fly_obj = $fb;
    }
    public function
setQuackBehavior(QuackBehavior $qb) {
       
$this->quack_obj = $qb;
    }
}

class
ModelDuck extends Duck {
    public function
__construct() {
       
$this->fly_obj = new FlyNoWay();
       
$this->quack_obj = new MuteQuack();
    }
    public function
display() {
        echo
"I'm a model duck!\n";
    }
}
$model = new ModelDuck();
$model->performFly();
$model->performQuack();
$model->setFlyBehavior(new FlyRocketPowered());
$model->setQuackBehavior(new Squeak());
$model->performFly();
$model->performQuack();
?>
Anonymous
12.08.2008 14:48
Apologies to tedmasterweb, since I was incorrect in my note just prior. His sanitizing method would work, since it is based on known values from a switch statement. I had read it too quickly as the more common method of simply appending ".php" to variable values used in include directives in order to ensure that included files are PHP files, like so in a common __autoload variety often seen in the wild:

<?php
function __autoload($class) {
    require_once(
"path/to/classes/$class.php");
}
?>

This was the sort of unsafe usage of the include directives I was commenting on.
Anonymous
12.08.2008 14:41
Tedmasterweb's point is a good one, though sanitizing inputs is often even more subtle than you would expect. For instance, his sanitizing solution would fail if the supplied driver name were "../../../../../../../../etc/passwd\0" (which, as you'll note, is null-byte-terminated). The underlying C-functions that run most modern POSIX-compliant and POSIX-based operating system filesystem operations will treat the ASCII null byte as a string termination character, and so will ignore the ".php" he appended to the path. Thus, this attack would still succeed. This attack is described in further detail here (the link is too long for the word wrapping, but it will still work):

http://us3.php.net/manual/en/security.filesystem.php
#security.filesystem.nullbytes

In my own __autoload functions, I tend to provide a validating regex for class or interface names to only allow characters I know are safe (though this code might have to be adjusted once namespace support is fully functional in PHP). For anyone who prefers to attempt to remove unsafe characters instead, I suggest the following list at a minimum:

period (for the ".." pseudo-directory), slash and backslash (for directory separators; both work on Windows systems), the explicit DIRECTORY_SEPARATOR constant, and the ASCII null byte (which can be typed in code as "\0").

Usage of the PHP functions escshellcmd or escshellarg might also be advisable, depending on how your code is written (particularly depending on whether it is executing a shell command or including a file).
tedmasterweb at gmail dot com
26.06.2008 21:21
Regarding Example #1:

Be sure to "sanitize" your variables before using them for including files.

Example #1 assumes the variable $type contains sanitized data (and NOT something threatening like '../../../../../etc/passwd').

One approach might be as follows:

<?php
switch ( $type ) {
    case
"MySQL":
       
$type = 'mysql';
        break;
    case
"SQLite":
       
$type = 'sqlite';
        break;
    default:
        throw new
Exception ('Driver not found');
}

if (include_once
'Drivers/' . $type . '.php') {
   
$classname = 'Driver_' . $type;
    return new
$classname;
} else {
    throw new
Exception ('Driver not found');
}

?>

Naturally, the examples are brief and intended to express the issue at hand, not input sanitizing methods, but someone might find this note helpful.

HTH
Alex (raffe) toader_alexandru at yahoo dot com
3.06.2008 20:04
Db layer design algorithm:
"Separation of database layer by database functionality"

First we draw this line:

Application
-------------
     DB

Here comes the new thing:
The db layer we separate it into two areas like this:

Db layer
       |
select | insert, update delete
       |

in the left side we have the select part.
The difference between the left and the right sides is that select side has no connection with the db structure - you can take data querying all table, while the right side is table oriented.

Select side:
Here all queries are in one file called "getters". Like getterUsers.

Inside it will be the body of the query but the fields that are to be selected will be build dynamically.
When calling this "getter" you will provide an array of fields to be selected or no fields, situation when it will take all fields.

To keep those db field names as low as possible in this architecture - so the above code dont need to know about the name of the fields in db, you will make just above this "getter", a "filter" file.
This filter will have a switch with a key and inside will call the getter with fields from db.
Ex:
<?php
switch(key)
case
'Label':
$fields = array("label", "firstName");
$obj->getUser($fields)
break;
?>

Above this filter you will have a "caller" that will call the "filter" with the key:
Ex:
<?php
function callerUserLabel()
{
->
filterUserLabel('Label');
}
?>

So in the higher code you just make
->callerUserLabel();
and this will return all what you need.

If you want this query to get out of the db and another field called "email", you just create another case in the switch and a "caller" to call that case.

Dynamic and extensible.

----------------

Now on the insert update side.
Here we only think in db tables.

First we do some "checkers" for all fields in db.
checkerTableName.php
This will contain an array with all the fields and the checks that must be done on that field and perform the checks only on the provided fields.

Then we do the "updaters". Those are build dinamically like the "getters" - if fields provided, only those updated. If all fields provided, can be used as an "inserter".

When performing an insert, all checks on that table will be done.

When performing an update on only one field - like updating a label, only that label will be checked to be in conformity with requirements like a length, special chars inside.
Dependency checks are made here also.

When having in one application action a multiple insert or update (when inserting an operator also add a webUser lets say) you do above those "inserter" and "updater" files a small "manager" that will do:
->checkOperatorFields();
->checkWebUserFields();

->insertOperator();
->insertWebUser();

If no error is thrown, all things will go nice and quiet.

Now also the "getters" will have their fields checked when needed using those checkers. I am talking about the values that are given as parameters not about the ones that are returned from db.

If you are working with domain objects or business logic objects (whatever you call them) above the db layer you will have to make below that line we first draw a "business logic asambler" object that will make from your data what you want.

If this dont exist, at least an intermediary layer that will map the names from db with the ones used in application must be done in both directions - from application to db and from db to application.

-------------------------------------

Advantages of this architecture:
- Usefull in complex application especheally where the selects are made ussually from many tables so you dont have to load lots and lots of files and to get lost in the logic for one simple select.
- NO DUPLICATE CODE
- Simple and intuitive.
- Flexible and expendable.

-----------
"A place where this idea is exposed completely or to debate on it:"

http://www.kurzweilai.net/mindx/show_thread.php?rootID=122913
Andrea Giammarchi
1.06.2008 19:49
A tricky way to implement Factory or Singleton is this one:
<?php

class A {
   
// your amazing stuff
}

// implicit factory
function A( /* one or more args */ ){
    return new
A( /* one or more args */ );
}

$a = A(1,2,3);
$b = A(2,3);

// or implicit Singleton
function A( /* one or more args */ ){
    static
$instance;
    return isset(
$instance) ? $instance : ($instance = new A( /* one or more args */ ));
}

A(1,2,3) === A(2,3); // true
?>

More details in WebReflection, byez
krisdover at hotmail dot com
21.05.2008 17:43
The Singleton pattern shown in the above example can still be broken by object serialization. e.g.

<?
class SingleFoo{
  private static
$instance;
  public
$identity = "in the end, there can be only one foo\n";

  private function
__construct() {}

  public static function
getInstance(){
      if(!
self::$instance){
         
self::$instance = new SingleFoo();
      }
      return
self::$instance;
  }

  public function
setIdentity($identity){
    
$this->identity = $identity;
  }

  public function
getIdentity(){
     return
$this->identity;
  }
}

$foo = unserialize( serialize(SingleFoo::getInstance()) );
$foo->setIdentity("new foo on the block\n");

print(
SingleFoo::getInstance()->getIdentity());
print(
$foo->getIdentity());

// result:
// in the end, there can be only one foo
// new foo on the block
?>

A possible solution to this problem involves using the magic method __wakeup() in the Singleton class to enforce the Singleton pattern during unserialization:

<?
class Singleton{
   
// ....

   
public function __wakeup(){
       if(!
self::$instance){
         
self::$instance = $this;
       }else{
         
trigger_error("Unserializing this instance while another exists voilates the Singleton pattern",
             
E_USER_ERROR);
       }
  }

 
// ....
}
?>

The unserialization would be permitted if it does not result in additional instances of the Singleton, and instances restored in this way would still be accessible via the Singleton static factory method.

Kris Dover
shane dot harter at midwayproducts dot com
13.05.2008 21:00
Re: Chris

Question re:  // Mangle the arguments into an array

Why not just use func_get_args() ? Am I missing something?

I mean, (no offense) but generally speaking I'm not a fan of what you put together.

I can see the benefit of abstracting the plumbing needed for a singleton in a common base class.

So I understand your thinking.

But I disagree with it. IMO creating a class hierarchy is about properly modeling a system (in the case of an event model) or an entity (in the case of a data model).

So instead of using inheritance to better solve a problem domain, I'm using it to handle an implementation detail.

IMO, creating an ISingleton interface to enforce continuity, and a code template of an empty class w/ all the required singleton programming would be much better.
someone at somewhere dot com
5.05.2008 10:20
If you want a singleton and you don't mind on throwing a stop error/exception when a 2nd instace is created instead of returning the already created object, then this code works with subclassing and without getInstace alike functions (just with __construct)

<?php

class SINGLETON
{
   
// the array for checking the created instances
   
protected static $singletons = array ();

   
// make it final so extended classes cannot override it
   
final public function __construct ()
    {
       
$classname = get_class ( $this );

        if ( ! isset (
self::$singletons[$classname] ) )
           
// instead of $this it could be any value since we are checking for isset, but a reference to the object may be useful in a possible improvement, somewhat
           
self::$singletons[$classname] = $this;
        else
           
// your favorite stop error here
           
trow new Exception ();
    }

   
// final as well, no overriding, plus protected so it cannot be called
   
final protected function __clone () {}
}

class
X extends SINGLETON
{
   
//...
}

class
Y extends X
{
   
//...
}

$x = new X ();
$y = new Y ();

$a = new X (); // execution stops, as an instance of X is created already

$b = new Y (); // execution stops, as an instance of Y is created already, it DOES NOT give problems with X, despite extending X

?>

so, if it is ok to stops the execution, this method is way simpler

it must stops the execution because no matter what, __construct will return a reference to the new object, always, so if the script goes on further you will have effectively 2 instances (as a matter of fact, the code above only checks the existence of another object from the same class, it does not prohibit the creation of a new one)

hth
Chris
18.04.2008 18:07
I cannot belive I was so stupid with my first note on this...

As any Singleton class forces a design pattern on to the user, and is really just a helper class for that design pattern, there is no reason not to force them to mangle any arguments into an array, which allows me to get rid of the use of the ReflectionClass and allows protected constructors.

If someone can delete the first note to hide my shame that would be great, and this bit of this one upto the ----- marker below :D

To save people the trouble of finding my previous note:

-----

This is a Singleton helper class inspired by Mattlock's Singleton class with interface.

It has the advantages of:

1) It uses only a single abstract class instead of an interface and class definition.
2) It allows for multiple instances of classes where you only wish to have one of any instance initialised with certain arguments such as connections to different databases, they may use the same class, but there will be one instance for each database.

This method should allow multiple child classes to extend the Singleton class, and only requires a small about of argument mangling to make it work.

<?php

abstract class Singleton
{
    static abstract public function
getInstance();

    static final protected function
getClassInstance($klass, $args=NULL)
    {
       
// Initialize array for $instances
       
if(self::$instances === NULL)
           
self::$instances = array();

       
// Initialize array for instances of $klass
       
if(!array_key_exists($klass, self::$instances))
           
self::$instances[$klass] = array();

       
// Create key from args
       
$key = serialize($args);

       
// Instantiate $klass
       
if(!array_key_exists($key, self::$instances[$klass]))
        {
               
self::$instances[$klass][$key] = new $klass($args);
        }

       
// Return instance of $klass
       
return self::$instances[$klass][$key];
    }

    static private
       
// Storage for all instances of Singleton classes
       
$instances;
}

final class
MySingleton extends Singleton
{
    static public function
getInstance()
    {
        return
Singleton::getClassInstance(__CLASS__);
    }

   
// Construct should be protected.
   
protected function __construct() {}
}

final class
NamedSingleton extends Singleton
{
    public
       
$name;

   
// Default arguments here NOT constuctor to prevent dupilicate instances.
   
static public function getInstance($name = 'Default')
    {
       
// Mangle the arguments into an array
       
$args = array('name' => $name);
        return
Singleton::getClassInstance(__CLASS__, $args);
    }

   
// Constructor must accept a single array containing all the arguments, if it wants to get any.
   
protected function __construct($args)
    {
       
$this->name = $args['name'];
    }
}

echo
'<pre>';

$a = MySingleton::getInstance();
$b = MySingleton::getInstance();
var_dump($a);
var_dump($b);

$c = NamedSingleton::getInstance();
$d = NamedSingleton::getInstance('Default');
$e = NamedSingleton::getInstance('Default');
var_dump($c);
var_dump($d);
var_dump($e);

echo
'</pre>';

?>
Chris
18.04.2008 16:11
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>';

?>
Chris N.
7.04.2008 18:27
I have read much of the debate between the singleton pattern and global variables.  I think there are two advantage the singleton has over a global variable.

1.) The singleton can provide protection of the data it holds.  The singleton class can define methods that will proper validate and store data.

2.) A singleton it more maintainable in two ways.  Changing the underlying data structure, say a string to an array, will take much less effort using a singleton than using a global variable where you would have to find every time the global variable is modified (which can be mitigated with regular expressions).  Second, the global variable can be changed and modified at any point in your code base which can cause problems with debugging large code bases, or code that relies on different libraries.

A practical example would be a way to log messages in an application.

With a global variable you can do:
<?PHP
$g_log
= '';
// or
$g_log = array();

// But at any point $log can be wiped out or changed. i.e.

$g_log = 42;

// Where as a singleton can't in inadvertently lose data.
class Log {
   public static function
instance() {
      static
$_instance = null;
      if (
is_null($_instance)) {
        
$_instance = new Log();
      }
      return
$_instance;
   }

   public function
logMsg($s) {
     
// Validate
      // Now add
  
}
}

$s_log = Log::instance();

// So if happens somewhere, unexpectedly
$s_log = 42;

// You will still have your log in the Log class and
$s_log->log("Hello World!");

/* Where as if $g_log was originally a string and you
wanted to change it to a global you would have to change */
$g_log .= 'Hello World!';
// to
$g_log[] 'Hello World!';
?>

If you change the underlying way in which the Log class stores the messages the above statement will not have to be changed.

If you want the speed or don't care about the security then use a singleton.  If you want the security or maintainability then use a singleton.

Finally, the best thing you can do is use a consistent coding style throughout your code no matter what approach you take.
Mattlock
21.02.2008 17:16
This allows for singleton functionality via class extension, and does not use any shady functions like eval.

<?php
interface ISingleton {
    public static function
GetInstance();
}

class
Singleton implements ISingleton {
    public static function
GetInstance($class='Singleton') {
        static
$instances = array();
       
        if (!
is_string($class)) {
            return
null;
        }
       
        if (
$instances[$class] === null) {
           
$instances[$class] = new $class;
        }
       
        return
$instances[$class];
    }
}

class
Mars extends Singleton implements ISingleton {
    public static function
GetInstance() {
        return
Singleton::GetInstance(get_class());
    }
}

class
Neptune extends Singleton implements ISingleton {
    public static function
GetInstance() {
        return
Singleton::GetInstance(get_class());
    }
}

$x = Mars::GetInstance();
echo
'<pre>'.print_r($x,true).'</pre>';

$x = Neptune::GetInstance();
echo
'<pre>'.print_r($x,true).'</pre>';
?>
me at chrisstockton dot org
17.01.2008 18:55
For anyone who reads: tims57 at yahoo dot com

Please let me show everyone a example of how a global variable is nothing like a singleton pattern. Take into considering the following. A global variable, cares not the state of its contents, it is only a container. If it contains a instance, a boolean, or a integer, it is all the same to it as PHP is dynamically typed it would be very easy for a global variable to be overridden by some dynamically loaded module in a complicated architecture, which could in turn cause a instance that maintains account or billing data to destruct before values are written to it.

The singleton is a means of protecting the instance to a single instantiation.

A global variable offers no such protection, it is only a container for a value.

<?php

$unreliableInstanceNotProtectedAtAll
= new StdClass;

class
Singleton
{
    static private
$_instance;
    private
$_foo = 'foo';
    private function
__construct() {}
    static public function
getInstance() {
        return isset(
self::$_instance) ?
           
self::$_instance : self::$_instance = new self();
    }
    public function
updateFoo($foo) {
       
$this->_foo = $foo;
    }
    public function
getFoo() {
        return
$this->_foo;
    }
}

/** Singleton offers protection from being instantiated multiple times */
// file_2481_r4.php, the early foo module not used except under certain circumstances
$foo = Singleton::getInstance();
var_dump($foo->getFoo()); // foo
$foo->updateFoo('bar');
var_dump($foo->getFoo()); // bar

// file_1444114_r1.php (author has no idea that file_2481_r4.php was loaded by
// the "foo" module", doesn't matter because the class will be instantiated only once
$foo = Singleton::getInstance();
var_dump($foo->getFoo()); // bar

/** Global variable just contains a instance, has no care for what it contains */
// file_2481_r4.php, the early foo module not used except under certain circumstances
$unreliableInstanceNotProtectedAtAll->foo = 'foo';

// file_1444114_r1.php (author has no idea that file_2481_r4.php was loaded by
// the "foo" module", doesn't matter because the class will be instantiated only once
$unreliableInstanceNotProtectedAtAll = new StdClass;
$unreliableInstanceNotProtectedAtAll->foo = 'bar';

?>
Alexandre at dontspamme gaigalas dot net
9.01.2008 22:01
Simplest PHP5 singleton implementation ever:

<?php
class Some_Class
{
    static private
$_i;
    private function
__construct()
    {
    }
    static public function
singleton() {
        return isset(
self::$_i) ? self::$_i : self::$_i = new self();
    }
}
?>
tims57 at yahoo dot com
31.12.2007 21:57
For anyone who reads: me at chrisstockton dot org

The note being refered to by that post is actually correct. A singleton provides essentially the same functionality as a global variable refering to an object combined with code to create the object at first use or application initialization. Using them is just a much more involved and difficult to follow technique involving class instantiation. Although perhaps appropriate in some circumstances, for many uses the global variable approach makes more sense.

The note being refered to is also correct regarding design patterns. Using design patterns and using interfaces should not be confused, they are nothing the same. Authors of 'pay-for software' (those 'large scale enterprise applications') have to get our laughs some way or another!

One final point neither note writer seems to get. PHP 5 accommodates many architectures, and is quite valuable for building scalable applications, even though it is still (thank God) free. PHP is now one of the 'big guys', and it needs these object oriented capabilities, even though they might be confusing to some.
me at chrisstockton dot org
25.09.2007 22:23
For anyone who reads: anonymous at world4ch dot org

Please do not confuse the singleton for a global variable, they are nothing the same. The global keyword is a way to extract a variable from the global scope into your local scope. A singleton is a way to control class instantiation, independent of scope to a single instance.

In addition note the importance in design patterns, the ability to interchange interfaces and abstraction to allow easy adaption to a variety of needs and specifications through a single means of access is invaluable to many large scale enterprise applications. Specially pay-for software that has many system architectures to accommodate. However, the comment makes a good point to implement as necessary, the many principles don't apply to every problem domain. Do not conform your problem to a pattern, implement a pattern to your problem.
anonymous at world4ch dot org
16.07.2007 10:37
A singleton is the "enterprise professional scalable business solution" version of a global variable. It'd be a good idea if this were the IOCCC, but since it isn't, it's better to simply say:

global $lol;

It's also faster and more maintainable, and has the same advantages and disadvantages.

Also, I'll advise against all "enterprise object-oriented industry-standard design patterns". Some of these patterns are correct, but their existence is not. Programming is not about copypasta. It's about thinking, abstracting and combinating. If you can't think of these patterns for yourself when you need them — and in the case of needing them, manage to abstract them so that your code doesn't become a copypasta fest, then you shouldn't be programming in the first place.

Furthermore, the existence of software patterns is a proof of the object-oriented model shortcomings. You shouldn't ever need to do any copypasta in your code. If something is done two or more times, you abstract it. And the language should support a way for you to. There's no reason for a "design pattern" to exist more than once, and since they are trivial (they better be trivial to you, if you are programming), you don't need to study them.

The best advice I can give you is that instead of reading "design patterns", you read Structure and Interpretation of Computer Programs (SICP), a book freely available from MIT where you will learn what you need to program properly in any programming language.
dario [dot] ocles [at] gmail [dot] com
19.06.2007 0:09
This's a example of Composite Pattern:

<?php
abstract class Graphic{
    abstract public function
draw();
}

class
Triangle extends Graphic{
    private
$name = '';

    public function
__construct($name = 'unknown'){
       
$this->name = $name;
    }

    public function
draw(){
        echo
'-I\'m a triangle '.$this->name.'.<br>';
    }
}

class
Container extends Graphic{
    private
$name = '';
    private
$container = array();

    public function
__construct($name = 'unknown'){
       
$this->name = $name;
    }

    public function
draw(){
        echo
'I\'m a container '.$this->name.'.<br>';
        foreach(
$this->container as $graphic)
           
$graphic->draw();
    }

    public function
add(Graphic $graphic){
       
$this->container[] = $graphic;
    }

    public function
del(Graphic $graphic){
        unset(
$this->container[$graphic]);
    }
}

$tri1 = new Triangle('1');
$tri2 = new Triangle('2');
$tri3 = new Triangle('3');

$container1 = new Container('1');
$container2 = new Container('2');
$container3 = new Container('3');

$container1->add($tri1);
$container1->add($tri2);
$container2->add($tri3);

$container3->add($container1);
$container3->add($container2);

$container3->draw();
?>

The above example will output:

I'm a container 3.
I'm a container 1.
-I'm a triangle 1.
-I'm a triangle 2.
I'm a container 2.
-I'm a triangle 3.

Dario Ocles.
baldurien at bbnwn dot eu
10.05.2007 0:49
uvillaseca at yahoo dot es :

Yes. In PHP singleton are dependent to a start page - unless if php is runt from a console - thus :

<?php
final class Foo {
  private
__construct() {
   
// read some static file like configuration file
 
}
  public static function
getInstance() {
    static
$instance = null;
    if (
null === $instance) $instance = new Foo();
    return
$instance;
  }
}
?>

The file is read each time someone hit the startpage (say "index.php" which would include "Foo.php", and which would call Foo::getInstance()).

Use of cache like APC may allow you to achieve a singleton which would work on the whole server instead of each incoming connexion (an incoming connexion that read a php page, like index.php, will run the script, use the singleton, read the static file, each time while if the singleton was stored like a global instance among each incoming transaction, then the file would be read only once).

However, it is hard to do some as you are not in Java and J2EE, where such is valid and thread safe :

<?php // note : this is java!
public final class Foo {
  private
Foo() {/*read our file*/}
  private static final
Foo instance = new Foo();
  public static final
Foo getInstance() {
    return
instance;
  }
}
?>
Because when Java load the class, a lock is acquired so that we only have one call to the constructor, this is equivalent :
<?php // note : this is java!
public final class Foo {
  private static final
Object synchrotron = new Object();
  private
Foo() {/*read our file*/}
  private static
Foo instance;
  public static final
Foo getInstance() {
   
synchronized (synchrotron) {
     
// force the thread to wait here
      // eg: only one thread is in that block
     
if (instance == null) {
       
instance = new Foo();
      }
      return
instance;     
    }
  }
}
?>
The comparison with Java is useful, because it means that you have some work to do to achieve a singleton that would work on the whole server instead of only each incoming connexion :

If you use APC, like this :

<?php
final class Foo {
  private
__construct() {
   
// append "blah" to a file
 
}
  public static function
getInstance() {
    if (
false === ($o = apc_fetch(__FUNCTION__)) {
     
$o = new Foo();
     
apc_store(__FUNCTION__, $o);
    }
    return
$o;
  }
}
?>

This would work. But, when two incoming connexion arise at the same exact moment, then you will append "blah" twice.

As for the one that said that singleton are a class with static method, no it is not. A singleton is polymorphic, where static method are simply the equivalent with a class namespace of function.

If you have a method or function that expect an object implementing interface A, then you will be able to use singleton implementing interface A.
Dave Miller
25.03.2007 12:12
Here's a way to make singleton classes with no extra code other than "extends Singleton" - if you use __AutoLoad() and keep each class in a separate file that is...

<?php

abstract class Singleton {
 
 
// Cannot be instantiated by any other class
 
protected function __Construct() { }
 
 
// Cannot be cloned ever
 
private function __Clone() { }
 
 
// Create/fetch an instance of the class
 
static public function getInstance($ClassName = null) {
   
    static
$Instance;
   
    if (
$Instance) {
      return
$Instance;
    } elseif (
$ClassName) {
     
$Instance = new $ClassName;
      return
$Instance;
    } else {
      return
null; // or throw exception if you want...
   
}
   
  }
 
}

function
__AutoLoad($ClassName) {
  include
"$ClassName.php";
  if (
is_subclass_of($ClassName, 'Singleton')) {
    eval(
$ClassName.'::getInstance($ClassName);');
  }
}

// ClassName.php
class ClassName extends Singleton {
 
// ... Code ...
}

// To use
$a = ClassName::getInstance();
$a->MyFunc();

?>

Of course you could do this differently - the point is that you can use __AutoLoad() to tell the single what class it is, unlike some other ways where this is done manually every time you define a singleton class.
david at bagnara dot org
28.12.2006 21:45
Thanks for the example below of an extendable Singleton. I have enhanced it a little so the derived class does not need to implement any functions. The technique to get an instance is now
$x = Singleton::connect( "derived_class_name")

<?php
class Singleton
{

/*
    How to use:
        extend new class from singleton
    To connect:
        $x = Singleton::connect( "CLASSNAME" ) ;
 */
   
private static
       
$instanceMap = array();

   
//protected constructor to prevent outside instantiation
   
protected function __construct()
    {
    }
  
   
//deny cloning of singleton objects
   
public final function __clone()
    {
       
trigger_error('It is impossible to clone singleton', E_USER_ERROR);
    }

    public function
connect(    // return a (reference to) a single instance of className
                   
$className  // name of a class derived from Singleton
                   
)
    {
       
// see if class already constructed
       
if(!isset(self::$instanceMap[$className]))
        {
           
// if not then make one
           
$object = new $className;
           
//Make sure this object inherit from Singleton
           
if($object instanceof Singleton)
            {
               
// save in static array
               
self::$instanceMap[$className] = $object;
            }
            else
            {
                throw
SingletonException("Class '$className' do not inherit from Singleton!");
            }
        }
       
// return reference to single instanace of className
       
return self::$instanceMap[$className];
    }
}

?>

<?php

class A extends Singleton
{
    protected
$rndId;
  
    protected function
__construct()
    {
       
$this->rndId = rand();
    }
  
    public function
whatAmI()
    {
        echo
'I am a ' . get_class( $this ) . ' (' . $this->rndId . ')<br />';
    }
}

class
B extends A
{
}

$a = Singleton::connect( "A" );
$b = Singleton::connect( "B" );
$a->whatAmI();// should echo 'I am a A(some number)
$b->whatAmI();// should echo 'I am a B(some number)

unset( $a ) ;

$c = Singleton::connect( "A" );
$d = Singleton::connect( "B" );

$c->whatAmI();// should echo 'I am a A(same number as above)
$d->whatAmI();// should echo 'I am a B(same number as above)

$a = new A();// this should fail
$b = new B();// this should fail

?>
eyvindh79 at gmail dot com
6.12.2006 18:48
A pure extendable(multiple sublevels) Singleton class in PHP seems impossible at the moment because of the way PHP handles static inheritance, but my class is close to what i want.

Very simple usage:

<?php
class Test extends Singleton {

    public static function
getInstance(){
        return
Singleton::getSingleton(get_class());
    }

}
?>

Singleton class implementation:

<?php
class Singleton {

   
/***********************
     * HOW TO USE
     *
     * Inherit(extend) from Singleton and add getter:
     *
     *  //public getter for singleton instance
     *     public static function getInstance(){
     *        return Singleton::getSingleton(get_class());
     *    }
     *
     */
   
   
private static $instanceMap = array();

   
//protected getter for singleton instances
   
protected static function getSingleton($className){
        if(!isset(
self::$instanceMap[$className])){
           
           
$object = new $className;
           
//Make sure this object inherit from Singleton
           
if($object instanceof Singleton){   
               
self::$instanceMap[$className] = $object;
            }
            else{
                throw
SingletonException("Class '$className' do not inherit from Singleton!");
            }
        }
       
        return
self::$instanceMap[$className];
    }   
   
   
//protected constructor to prevent outside instantiation
   
protected function __construct(){
    }
   
   
//denie cloning of singleton objects
   
public final function __clone(){
       
trigger_error('It is impossible to clone singleton', E_USER_ERROR);
    }   
}
?>

Just a simple test case:

<?php
class A extends Singleton {
   
    protected
$rndId;
   
    protected function
__construct(){
       
$this->rndId = rand();
    }   
   
    public function
whatAmI(){
        echo
'I am a A('.$this->rndId.')<br />';
    }

    public static function
getInstance(){
        return
Singleton::getSingleton(get_class());
    }

}

class
B extends A {

    public function
whatAmI(){
        echo
'I am a B('.$this->rndId.')<br />';
    }
   
    public static function
getInstance(){
        return
Singleton::getSingleton(get_class());
    }

}

$a = A::getInstance();
$b = B::getInstance();

$a->whatAmI();// should echo 'I am a A(some number)
$b->whatAmI();// should echo 'I am a B(some number)

$a = A::getInstance();
$b = B::getInstance();

$a->whatAmI();// should echo 'I am a A(same number as above)
$b->whatAmI();// should echo 'I am a B(same number as above)

$a = new A();// this should fail
$b = new B();// this should fail

?>

I hope this helps.
-Eyvind-
suki at psychosensor dot de
30.09.2006 2:38
cortex is right - it took me hours to figure it out. None the less it's sometimes useful to let one sigleton class extend another. You can achieve this by only using static attributes:

<?php
 
class A {
    private static
$value = 0;
    private static
$instance = null;
   
    private function
__construct() {
     
$this->set(time());
    }
   
    public static function
getInstance() {
      if (
is_null((self::$instance))) {
       
$class_name = __CLASS__;
       
self::$instance = new $class_name;
      }
     
      return
self::$instance;
    }
   
    private function
set($i) {
     
self::$value = $i;
     
$this->out();
    }
   
    public function
out() {
      echo
self::$value;
    }
  }

  class
B extends A {
    public static
$instance = null;
   
    public static function
getInstance() {
     
parent::getInstance();
      if (
is_null(self::$instance)) {
       
$class = __CLASS__;
       
self::$instance = new $class;
      }
      return
self::$instance;
    }
  }

 
$b = B::getInstance();
 
$b->out();
?>

This will output the current time twice. If $value isn't static, the call to $b->out() will output 0. Maybe it can save someone some time...
Dennis
11.08.2006 21:19
An easy way to have your singleton persistent between page loads:

/**
 *    Returns an instance of the singleton class.
 *    @return    object        The singleton instance
 */
public static function _instance()
{
    // Start a session if not already started
    Session::start();
   
    if ( false == isset( $_SESSION[ self::$_singleton_class ] ) )
    {
        $class = self::$_singleton_class;
        $_SESSION[ self::$_singleton_class ] = new $class;
    }
   
    return $_SESSION[ self::$_singleton_class ];       
}

/**
 *    Destroy the singleton object. Deleting the session variable in the
 *    destructor does not make sense since the destructor is called every
 *    time the script ends.
 */
public static function _destroy()
{
    $_SESSION[ self::$_singleton_class ] = null;
}

/**
 *    Initialize the singleton object. Use instead of constructor.
 */
public function _initialize( $name )
{
    // Something...
}

/**
 *    Prevent cloning of singleton.
 */
private function __clone()
{
    trigger_error( "Cloning a singleton object is not allowed.", E_USER_ERROR );
}

private static $_singleton_class = __CLASS__;
daniel at basegeo dot com
2.08.2006 21:55
Ubaldo, you cannot expect to get the same instance using the Singleton pattern on different runs of the script.

Each time you execute index.php it's a new runtime environment. It's like executing several times Notepad, each run is unrelated to the others.

As your scripts grow in size, and you modularize code used on many pages into classes and libraries you'll realize how useful the Singleton pattern is. For instance, you can create a database abstraction class that you can call from many places and always be asured it's a single instance... in this case that means a single connection to the database.

Hope this clarifies the issue for you.
uvillaseca at yahoo dot es
7.07.2006 18:59
I don't know if it's useful has a singleton that is a singleton only inside a script. By example, having the following scripts:

<?php
//index.php
require_once("Singleton.php");
$p = Singleton::getInstance();
$s = Singleton::getInstance();
?>

<?php
//Singleton.php
class Singleton {
    private static
$instance;

    private function
__construct() {
       
    }
    public static function
getInstance() {
        if(!isset(
self::$instance)) {
            echo
'creating singleton';
           
self::$instance = new self;
        }
        return
self::$instance;
    }
}
?>

Calls to index.php always returns the message 'creating singleton', so a new instance of the class is created for each call to index.php; and this is not the behaviour that I'd expect.

Best regards,

Ubaldo
cortex at pressemicro dot net
2.06.2006 22:27
It's often forgotten, but a singleton class MUST be final. So it's useless to have a base class that implements the pattern and to inherit of it. That's why it's called a pattern and not a class library.

Here a little example that will show why.

<?php
class A {
// singleton pattern with getInstance static method
private $var; // A ressource variable
function __construct() {
   
$this->var = "get a ressource that could only  be taken one time by process";
}
}

class
B extends A {
// singleton pattern
function __construct() {
   
parent::__construct();
}
}

$anA = A :: getInstance();
$aB = B :: getInstance(); // try to get a second ressource, :(

?>

When developping class A, you may have think to be the only one with a $var ressource, but it's completly wrong. As $aB is an A (Think that there is two A instanciate and one with more than just A), $anA and $aB will have a different ressource variable and thus two different database connection for eg.

You'd never know how will be used your code, so you need to make it strong. This is the way of poo thinking.
lycboy at gmail dot com
29.04.2006 12:15
I don't agree to take a class with only static members and static methods as a 'singleton'. According to GoF's book, the singleton pattern means a class that only have one instance. A class containing only static members and functions still can be instantiated and extended, it have multiple instances. Consider the code below:
<?php

class StaticTest
{
    private static
$_test = "aaa";
   
    public static function
test()
    {
        echo
self::$_test;
    }
}

$obj = new StaticTest();

?>
The code will not report errors(although it's useless). So there can be many instances of the class.

It's reasonable that there is a class that create and store a unique instance of another class. Such as:
<?php

class A
{
    private
$_id = 0;
    public function
getId()
    {
        return
$this->_id;
    }
}

class
B
{
    private static
$_instance;

    public static function
singleton()
    {
        if (!isset(
self::$_instance)) {
           
self::$instance = new A();
        }
        return
self::$instance;
    }
}

?>
Here class B act as a guard to class A. But as same as the first section, it's useless too! Unless you can make sure that the users of your class will never find the class A, you shouldn't make the class you wanna to be unique can be instantiated many times.

So the best way to create a unique instance of a class is that the class save the unique instance itself. It is the core meaning of singleton pattern. Any information that mentioned here can be found in the book of GoF. I think it's worth reading the book.

BTW: It's allowed that there are a few of subclasses of a singleton class.
contact_us at haltebis dot com
19.03.2006 3:27
Here is my PHP5 Singleton only ("no getInstances()")

<?php
#file class.singleton.php
class singleton
{
   var
$instance;

   function
__construct()
   {
      static
$instances=array();
     
$class = get_class($this);
      if(!isset(
$instances[$class])) $instances[$class] = $this;
      foreach(
get_class_vars($class) as $var => $value)
      {
        
$this->$var = &$instances[$class]->$var;
      }
     
$this->instance = &$instances[$class];
   }

   function
__set($name,$value)
   {
      
$this->$name = $value;
       if(!isset(
$this->instance->$name)) $this->instance->$name = &$this->$name;
   }

}
?>

And here is the SimpleTest unit that I use

<?php
#file test.singleton.php

class singleton_example extends singleton
{
   var
$x;
   var
$y;

   function
__construct()
   {
     
parent::__construct();
   }
}

class
singleton_example2 extends singleton
{
   var
$x;
   var
$y;

   function
__construct()
   {
     
parent::__construct();
   }
}

class
TestOfSingleton extends UnitTestCase
{
   function
TestOfSingleton()
   {
     
$this->UnitTestCase();
   }

   function
testSet_and_Get1()
   {
     
$test1 = new singleton_example();
     
$test1->x = 'a';;
     
$test1->y = 'b';

     
$test2 = new singleton_example();
     
$test2->x = 'c';
     
$test2->y = 'd';
     
$test2->z = 'e';

     
$test3 = new singleton_example2();

     
$this->assertEqual($test1->x,'c');
     
$this->assertEqual($test1->y,'d');
     
$this->assertEqual($test1->z,'e');

     
$this->assertEqual($test3->x,null);
     
$this->assertEqual($test3->y,null);
   }
}
?>

Never failed me until now
vsviridov at exceede dot com
30.01.2006 5:39
Singleton is a very useful pattern if you need multiple instances of different classes to use only one unique instance of common class. It's not just about having static methods.

e.g. Your database connection class probably should be a singleton, in order to spare all redundant connect calls, etc...
toomuchphp-phpman at yahoo dot com
27.11.2005 14:46
The principle of the Singleton pattern can easily be expanded to form [what I have dubbed as] the 'Unique' pattern - where a particular class may have several instances, each with a 'Unique ID'.  This can be useful when a single instance is required for each database record.

<?php

 
// Each instance of 'Customer' represents one customer!
 
class Customer {

    
// Access a unique instance of class for a customer record
    
public function Unique($CustomerID) {
       static
$instances = array();

      
// a unique instance for each CustomerID
      
if(!isset($instances[$CustomerID]))
        
$instances[$CustomerID] = new Customer($CustomerID);

       return
$instances[$CustomerID];
     }

     private
$CustomerID;

     private function
__construct($CustomerID) {
      
$this->CustomerID = $CustomerID;
     }
  }

 
// get instance of class for customer #1
 
$C1 = Customer::Unique(1);

 
// get instance of class for customer #2
 
$C2 = Customer::Unique(2);

?>
peetersdiet at gmail dot com
1.11.2005 14:02
As i reread my previous post i noticed 1 minor error. Namely that it is best to declare the singletonFactory()-method protected if u don't need to be able to use the method publicly. This way the implementation incorporates even better encapsulation.
peetersdiet at gmail dot com
31.10.2005 16:57
@ steffen at morkland dot com:

Interesting problem and u are right about always having to put the non-public constructor and public singleton-method in the classes that need to be singletons. U are also right about an interface not being able to declare a constructor private or protected.

Why not store all singletons in a static variable of a common parent class and make singleton-capability available to all childclasses? We can accomplish this by adding a hybrid singletonFactory()-method in that parent class and make the constructor of the childclass protected to enforce the singleton-pattern. At this moment all childclasses can be a singleton! Not to robust.

U can have childclasses implement the Singleton-interface as specified in ur post so classes can be tested on implementing this interface. If u always implement the interface on ur singleton-classes u can add a test to the singletonFactory()-method to check whether the class u are about to instantiate does implement the Singleton-interface. Together with the enforced prototyping of the singleton()-method this provides a more foolproof usage of the singleton-pattern.

The singleton code is implemented in the parent so no rewriting of the code is necessary, thus avoiding programmer mistakes in the childclasses and keeping the code cleaner to the eye. The only methods the childclass needs are a protected constructor to avoid direct instantiation and a wrapping singleton()-method.

<?php
// As stated by steffen we can't restrict visibility of the constructor in an interface
interface Singleton {
    public static function
singleton();
}

// Parent class:
// U can define these methods at the highest level so the singleton-functionality
// is available to all objects, but it works at all levels of an object hierarchy.
class ParentClass {
    private static
$childSingletons = array();  // store singletons for each childclass
   
   
public static function singletonFactory($class='')
    {
        if (!isset(
self::$childSingletons[$class])) {   // singleton not loaded?
           
if (include_once($class.'.php')) {  // classfile included?
               
$thisClass = __CLASS__;
               
$object = new $class;
                if (
$object instanceof $thisClass) { // class is childclass? (so we can access the protected constructor)
                   
$classImplements = class_implements($object);
                    if (isset(
$classImplements['Singleton'])) {   // class implements Singleton?
                       
self::$childSingletons[$class] = new $class;
                    } else {
                        throw new
Exception ('Class \''.$class.'\' does not implement interface Singleton');
                    }
                } else {
                    throw new
Exception ('Unknown class \''.$class.'\'');
                }
            } else {
                throw new
Exception ('Class \''.$class.'\' not found');
            }
        }
        return
self::$childSingletons[$class];
    }
}

// Child class:
// 1. Define the constructor as protected.
// 2. Implement interface Singleton ...
//      ... to enforce prototype of singleton()
//      ... to be able to dynamically identify the class as a singleton.
// 3. Define the singleton()-method acting as a wrapper for the parent's singletonFactory()-method.
class ChildClass extends ParentClass implements Singleton{
    protected function
__construct() {}
   
    public static function
singleton() {
        return
parent::singletonFactory(__CLASS__);
    }
}

// public usage
$singleton = ChildClass::singleton();
?>

If u prefer more loose programming u can leave the Singleton interface out of the picture alltogether and create your childsingletons directly with the singletonFactory()-method. This approach only needs the protected constructor(), no singleton()-method. I know this approach allows all the childclasses to be treated as singletons. In my opinion this is not a problem, but the lack of robustness and absence of dynamic testability is. ;)
steffen at morkland dot com
11.10.2005 16:47
Regarding the singleton pattern, you have to create the function for every singleton class you want to have, because settting a variable static will set the variable on all instances of the class, and second of all, by extending a singleton class, you are breaking rule No #1 of the singleton pattern. an instance of a given type may only excist ONCE, by extending the singleton class you have multiple instances of the singleton class, and by is sharing the static $instance variable.

on thing could be done though, to make sure a programmer does not make any mistakes when creating singleton classes, an interface could be made, to make sure the singleton class is correctly defined.

it could look something like this:

<?php
interface singleton {
    public static function
getInstance();
}
?>

however, this interface does NOT force the programmer to make the constructor private, and don't even bother to try, it would just result in a error.

sorry to say it guys, there are no easy way around this one. not even a factory class can do the job for you since, the constructor must be private, to ensure that only one instance excists.
axon dot wp a at t wp dot pl
5.10.2005 18:25
Short version of Singleton:
<?php
public function __clone()
    {
       
trigger_error('Clone is not allowed.', E_USER_ERROR);
    }
?>
   
is :
<?php private function __clone() {} ?>
rashkatsa
30.09.2005 14:03
Hi there,

As Singleton patterns are used for years in Java, today we tend toward overriding 'new' operator (as singleton returns always the same instance for every 'new' that you call...). In order to do this, we use IoC (http://www.martinfowler.com/articles/injection.html). With lightweight container, you delegate the 'new' to a specific factory which decides if it has to return a new instance on each call or always the same instance. You homogenize your code as you don't have "new MyClass()" and "MyClass2::getInstance()" but always the same call : Component::get(MyClass) and Component::get(MyClass2). [PHP implementation hint : You can choose the parameter of the get method : class, classname, ...]. It's the component which decides if it has to return a new instance or not.

If you take a look at Java Spring framework (which use getBean(Class) method) or PicoContainer (which use getComponentInstance(Class) method - see 2 minutes tutorial on their site), you can configure the behavior for your class in an XML file (choosing that ClassA is a singleton and ClassB is not). With this configuration, you don't need to pollute your class code with _instance field but you just create a standard class (non invasive pattern).

when you would have a PHP generic component (class) factory, you can go further and build a complete PHP IoC (if it not already exists :)) and then the component factory injects dependencies itself (choose through constructors or mutators).

regards,

rashkatsa.
lukas dot starecek at centrum dot cz
17.07.2005 10:12
If you need singleton of any class and don't want write singleton wrapper for each this class, try this:

class UniverzalSingleton {

    const EXCEPTION_NO_CLASS = 1;

    protected static $_instances = array();

    public static function getInstance($class) {
        if (!isset(self::$_instances[$class])) {
            if (!class_exists($class))
                throw (new Exception(__CLASS__ . ': Requsted class is not exist.', self::EXCEPTION_NO_CLASS));
            self::$_instances[$class] = new $class();
        } // if
        return self::$_instances[$class];
    } // getInstance

} // class UniverzalSingleton
disappear dot nz at gmail dot com
8.07.2005 8:57
Hi ,

Singleton Patterns are excellent ,
I have created a singleton pattern that enables any class to be loaded from the one modular singleton library.

<?php

   
class singleton
   
{
        private static
$o_instance = NULL ;

        public static function
call_singleton ( $s_class )
        {
            if (
class_exists ( $s_class ) )
            {
                if (
self :: $o_instance === NULL )
                {
                   
self :: $o_instance = new $s_class ;
                }
            }           
            return
self :: $o_instance ;
        }
    }

?>
php at mijav dot dk
7.07.2005 18:46
Please use design patterns as they were intended:

Design patterns are designs that are known to solve common problems, such as having only 1 instance of a class. Design patterns are are not code libraries.
Most design patterns, if not all, have alternate implementations but common to them all is that the recommended implementation solves the problem.

Singleton should not be made as a class and then extended. Nor shuld __autoload be used.
Autoloading is very PHP-specific (and there might be nothing wrong with that, but design patterns are general patterns that are abstracted from the implementing language).
Making a class that you extend is very ugly. What if you have to extend that class too? You will have to make a dummy that extends your singleton class, just so you can extend the class you want. This is a very "ugly" solution that completely overrules the idea of well known design patters: A thought-though idea that works the way intended.

The manual shows a PHP implementation of the standard Singleton-pattern without "nifty" modifications.

To finish off this lesson on design patterns, I would like to ackknowledge that there is nothing wrong in tweaking patterns to suit your needs.
But remember: "If it isn't broken - don't fix it".

3.07.2005 8:28
Here's an effective strategy for creating singletons.

1.) define an __autoload() function

2.) Define all properties of a class to be static

3.) Make the constructor private.

Now, anywhere in your code, you can simply do as follows:

Class::Function();

The __autoload() function will take care of loading the class.

It's even better when you use the auto_prepend directive to define __autoload(). Now you can create a php script which looks like this:

<?php
TemplateSystem
::Start();
echo
'This is just a test!';
TemplateSystem::Stop();
?>

Now you've effectively got a 2-line solution to all templating issues, the templates will be available to every script, and the only additional overhead that you'll have for scripts that don't use the templating system is a 3-line autoload function!

Obviously, there's still a problem with __autoload() if you are attempting to write a templating system that has to work with someone else's software that also defines __autoload(). The best advice I can give here is to remove one of the __autoload()'s and modify the other to work with both.
traxer ad gmx.net
3.06.2005 0:29
In response to Richard Quadling's response to Scott Mattock's response to Jimmy Paterson ...

The singleton pattern is a /pattern/, not a class. There is no way to move the whole functionality of 'being a singleton' into a common base class, it was not intended that way. There is no point in adding features to derived classes, other than for internal use, either. Furthermore, when I derive two classes from Singleton, the singleton is not really a singleton anymore. Considering this, I think your implementation of Singleton and SubClass (i.e your correction to Scott Mattock's) is the one that most closely matches the intention of GOF. You can allow sublasses of SubClass, though:

<?php
class Singleton {
    private static
$instance;
    public static function
singleton($class = __CLASS__) {
        if (!isset(
self::$instance))
           
self::$instance = new $classname;
        return
self::$instance;
    }
}
class
SubClass extends Singleton {
    public static function
singleton($class = __CLASS__) {
        return
parent::singleton($class);
    }
}
class
SubSubClass extends SubClass {
    public static function
singleton($class = __CLASS__) {
        return
parent::singleton($class);
    }
}
?>

This even works with php4 if you
1. move the Singleton::$instance into function Singleton::singleton,
2. get rid of the unsuported keywords and
3. rename the Singleton::singleton method (so as not to be a constructor).
So no real imporvement here, except for the added protection of not beeing able to create objects explicitly.
anon at anon dot org
23.05.2005 22:02
After programming a number of real world applications with PHP, I found that this version of the singleton doesn't really resemble other singleton patterns, but is the only one I've ended up using and it works great.

<?php

class User {
  
/* .. your code, nothing specific matters in the class .. */
}

function
user(){
    static
$user;
    if(!isset(
$user))
       
$user = new User();
    return
$user;
}

//creates the user object then calls a method on it
user()->doSomething();

//calls a method on the same object
user()->doSomethingElse();

?>

Note that it is *possible* to create multiple instances of User, but in your API docs, or when you tell people how to use the class just say you are supposed to refer to it only via the user() function, and then there should be no reason to enforce it in your code any other way.

Also note that this syntax is only possible in PHP 5 because of the object / function dereferencing feature.  user()->someMethod(); will throw a fatal error in 4.x
dmnEe0 at gmail dot com
14.05.2005 23:13
I struggled a few hours on writing a simple Generic factory method for dynamic object factoring. I initially went for call_user_func_array() to create the object but that obviously didn't work. An anonymous function was what I needed. Here's the result (PHP5):

<?php
/**
 *    Name:    Factory
 *    Author:    Ezku
 *    Contact:    dmnEe0 at gmail dot com
 */
class Factory
{
   
/**
     * Generic factory method
     * @param string    Path to class definition
     * @param string    Basic class name
     * @param string    Derived class name
     * @param array    Class constructor arguments, optional
     */
   
public static function Generic($filename, $base, $derived, $args = array())
    {
       
/**
         * Check that the file exists
         */
       
if(file_exists($filename))
        {
            include_once
$filename;
           
/**
             * Check that the file contained the appropriate class definition
             */
           
if(class_exists($derived))
            {
               
/**
                 * Create argument list for constructor
                 */
               
$arglist = array();
                for(
$i = 0, $n = count($args); $i < $n; $i++)
                   
$arglist[] = '$args['.$i.']';
               
$arglist = implode(',',$arglist);
               
               
/**
                 * Create new instance via an anonymous function
                 */
               
$new_class = create_function('$name, $args', 'return new $name('.$arglist.');');
                return
$new_class($derived, $args);
            }
            else
                throw new
Exception("Definition file ($filename) did not contain definition for the $base class <code>$derived</code>");
        }
        else
            throw new
Exception("Definition file ($filename) for the $base class <code>$derived</code> was not found");
    }
}

/**
 * Useless usage example:
 */
function createCat($name, $scary_eyes = FALSE, $whiskers = TRUE)
{
   
$path = PATH_ANIMALS.'/'.$name.'.php';
   
$base = 'Cat';
   
$derived = $name.$base;
   
$args = array($scary_eyes, $whiskers);
    return
Factory::Generic($path, $base, $derived, $args);
}

// Create a MeowCat with scary eyes and whiskers
$cat = createCat('Meow', TRUE);
// Do whatever
?>
richard dot quadling at bandvulc dot co dot uk
19.04.2005 14:29
Singletons and subclasses will fail because __construct has to be public SOMEWHERE in the base class and cannot be hidden in sub classes. Even if the base class is an abstract class (which helps a little).

You can get abstract base class and singleton sub class working fine EXCEPT that you can create an instance of the subclass if you use new class(); rather than class::singleton();

So. After many hours of trial and error, no mixing of singletons and subclasses.
richard dot quadling at bandvulc dot co dot uk
19.04.2005 9:39
Further to my note. If you think I called the wrong method in the last line of code ...

$subclass2Instance->TellMe();

Notice I am using the SECOND subclass but a method from the FIRST subclass. This should be the clue to see that multiple subclasses of a base singleton class don't work.

If you try to call ...

$subclass2Instance->TellMeMore();

you get, as expected, a fatal error ...

Fatal error: Call to undefined method SubClass::TellMeMore()

Hope that clarifies things.
richard dot quadling at bandvulc dot co dot uk
18.04.2005 17:06
In response to Scott Mattocks response to Jimmy Paterson ...

You cannot mix singletons and subclasses securely.

Why?

The standard way of creating a singleton is with the method ...

   // Hold an instance of the class
   private static $instance;

   // The singleton method
   public static function singleton()
   {
       if (!isset(self::$instance)) {
           $c = __CLASS__;
           self::$instance = new $c;
       }

       return self::$instance;
   }

This returns either the previously created instance or a new instance of this class.

As the constructor is private (which inhibits the manual creation of the class), you cannot alter the value of $c in the example above by passing it to the function, as suggested by Scott Mattocks.

Why? __construct() is private!!!!

self::$instance = new $c;

where $c is NOT Singleton will result in a fatal error ...

Fatal error: Call to private Singleton::__construct().

You have to have __construct() as private, otherwise you can create multiple instances of the singleton, explicit contra the reason for the pattern to start with.

Now. Say you do make the __construct() protected (can only be called from this class or subclasses), then you MAY have a little more success.

But not much ...

<?php

class Singleton
{
 
// Hold an instance of the class
 
private static $instance;
 
 
// A private constructor; prevents direct creation of object
 
protected function __construct()
  {
      echo
'I am constructed';
  }
 
// The singleton method
 
public static function singleton($classname = __CLASS__)
  {
      if (!isset(
self::$instance)) {
         
self::$instance = new $classname;
      }
      return
self::$instance;
  }
}
class
SubClass extends Singleton {
   public static function
singleton()
   {
       return
parent::singleton(__CLASS__); // NOTE The singleton method MUST return an instance.
  
}
   public function
TellMe()
   {
       echo
'You are in here.';
   }
}

$subclassInstance = SubClass::singleton();
$subclassInstance->TellMe();
?>

gives you ...

I am constructedYou are in here.

But you are not going to be able to extend this to more than 1 subclass as the singleton exists for the base class ...

<?php

class Singleton
{
 
// Hold an instance of the class
 
private static $instance;
 
 
// A private constructor; prevents direct creation of object
 
protected function __construct()
  {
      echo
'I am constructed';
  }
 
// The singleton method
 
public static function singleton($classname = __CLASS__)
  {
      if (!isset(
self::$instance)) {
         
self::$instance = new $classname;
      }
      return
self::$instance;
  }
}
class
SubClass extends Singleton {
   public static function
singleton()
   {
       return
parent::singleton(__CLASS__); // NOTE The singleton method MUST return an instance.
  
}
   public function
TellMe()
   {
       echo
'You are in here.';
   }
}

class
SubClass2 extends Singleton {
   public static function
singleton()
   {
       return
parent::singleton(__CLASS__); // NOTE The singleton method MUST return an instance.
  
}
   public function
TellMeMore()
   {
       echo
'You are over here.';
   }
}

$subclassInstance = SubClass::singleton();
$subclassInstance->TellMe();

$subclass2Instance = SubClass2::singleton();
$subclass2Instance->TellMe();
?>

results in ...

I am constructedYou are in here.You are in here.

and NOT

I am constructedYou are in here.You are over here.

as you might have thought.

Basically, subclassing and singletons don't really mix.
scottmattocks at php dot net
6.04.2005 18:40
In respone to JimmyPaterson:

Since the singleton method isn't declared final, you can override it in the children classes. First you have to change the singleton class a little to accept a classname parameter.

class Singleton
{
   // Hold an instance of the class
   private static $instance;
 
   // A private constructor; prevents direct creation of object
   private function __construct()
   {
       echo 'I am constructed';
   }

   // The singleton method
   public static function singleton($classname)
   {
       if (!isset(self::$instance)) {
           self::$instance = new $classname;
       }

       return self::$instance;
   }
}

class SubClass extends Singleton {
    public static function singleton()
    {
        parent::singleton(__CLASS__);
    }
}

$singletonInstance = SubClass::singleton();
JimmyPaterson at gmx dot de
22.03.2005 2:55
Since the `__CLASS__` constant is used, the Singleton pattern won't work as a Base Class which you would want to implement into your classes.
Thus the following will _not_ work:
<?php

class Singleton
{
   private static
$_instance;
  
   final private function
__construct() { }
   public static function
getSingleton()
   {
      if(!isset(
self::$_instance))
      {
        
$tmpName    = __CLASS__;
        
self::$_instance = new $tmpName;
      }
      return
self::$_instance;
   }
  
   public function
NameSingletonClass()
   {
      echo
__CLASS__;
   }
   public function
__clone() { }
}

class
MyClass extends Singleton
{
   public function
NameMyClass()
   {
      echo
__CLASS__;
   }
}

$instance = MyClass::getSingleton();
$instance->NameSingletonClass();
// you'll get a nice `Call to undefined method Songleton::NameMyClass()` Error
$instance->NameMyClass();

?>
Kind of stupid if one has to write a Singleton-Pattern for each Class... or did I miss something?



PHP Powered Diese Seite bei php.net
The PHP manual text and comments are covered by the Creative Commons Attribution 3.0 License © the PHP Documentation Group - Impressum - mail("TO:Reinhard Neidl",...)