1--TEST-- 2ZE2 Late Static Binding and Singleton 3--FILE-- 4<?php 5abstract class Singleton 6{ 7 static private $instances = array(); 8 static private $nextInstanceId = 0; 9 private $instanceId = NULL; 10 static final public function getInstance() 11 { 12 $caller = get_called_class(); 13 if (!isset(self::$instances[$caller])) { 14 self::$instances[$caller] = new $caller; 15 self::$instances[$caller]->instanceId = self::$nextInstanceId++; 16 } 17 return self::$instances[$caller]; 18 } 19 public final function getInstanceId() 20 { 21 return $this->instanceId; 22 } 23 public final function identify() 24 { 25 var_dump($this); 26 } 27} 28 29class Foo extends Singleton { 30} 31 32class Bar extends Singleton { 33} 34 35class Baz extends Bar { 36} 37 38$u = Foo::getInstance(); 39$v = Bar::getInstance(); 40$w = Baz::getInstance(); 41 42$u->identify(); 43$v->identify(); 44$w->identify(); 45 46$x = Foo::getInstance(); 47$y = Bar::getInstance(); 48$z = Baz::getInstance(); 49 50$u->identify(); 51$v->identify(); 52$w->identify(); 53$x->identify(); 54$y->identify(); 55$z->identify(); 56?> 57--EXPECTF-- 58object(Foo)#%d (1) { 59 ["instanceId":"Singleton":private]=> 60 int(0) 61} 62object(Bar)#%d (1) { 63 ["instanceId":"Singleton":private]=> 64 int(1) 65} 66object(Baz)#%d (1) { 67 ["instanceId":"Singleton":private]=> 68 int(2) 69} 70object(Foo)#%d (1) { 71 ["instanceId":"Singleton":private]=> 72 int(0) 73} 74object(Bar)#%d (1) { 75 ["instanceId":"Singleton":private]=> 76 int(1) 77} 78object(Baz)#%d (1) { 79 ["instanceId":"Singleton":private]=> 80 int(2) 81} 82object(Foo)#%d (1) { 83 ["instanceId":"Singleton":private]=> 84 int(0) 85} 86object(Bar)#%d (1) { 87 ["instanceId":"Singleton":private]=> 88 int(1) 89} 90object(Baz)#%d (1) { 91 ["instanceId":"Singleton":private]=> 92 int(2) 93} 94