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===DONE=== 58--EXPECTF-- 59object(Foo)#%d (1) { 60 ["instanceId":"Singleton":private]=> 61 int(0) 62} 63object(Bar)#%d (1) { 64 ["instanceId":"Singleton":private]=> 65 int(1) 66} 67object(Baz)#%d (1) { 68 ["instanceId":"Singleton":private]=> 69 int(2) 70} 71object(Foo)#%d (1) { 72 ["instanceId":"Singleton":private]=> 73 int(0) 74} 75object(Bar)#%d (1) { 76 ["instanceId":"Singleton":private]=> 77 int(1) 78} 79object(Baz)#%d (1) { 80 ["instanceId":"Singleton":private]=> 81 int(2) 82} 83object(Foo)#%d (1) { 84 ["instanceId":"Singleton":private]=> 85 int(0) 86} 87object(Bar)#%d (1) { 88 ["instanceId":"Singleton":private]=> 89 int(1) 90} 91object(Baz)#%d (1) { 92 ["instanceId":"Singleton":private]=> 93 int(2) 94} 95===DONE=== 96