|
<?php |
|
class ClassObject |
|
{ |
|
const METHOD_NEW = 'new'; |
|
|
|
private static $classObjectInstances = []; |
|
|
|
private $className; |
|
|
|
public static function get ($className) |
|
{ |
|
$className = (string) $className; |
|
$selfClass = \get_called_class(); |
|
|
|
self::initializeClassObjectInstancesForSelfClass($selfClass); |
|
|
|
return self::getInstanceOfClassObject($selfClass, $className); |
|
} |
|
|
|
public function __call ($method, $arguments) |
|
{ |
|
$callback = [$this->className, $method]; |
|
if (\is_callable($callback)) { |
|
return \call_user_func_array($callback, $arguments); |
|
|
|
} elseif ($method === self::METHOD_NEW) { |
|
$reflection = ClassObjectReflection::get($this); |
|
return $reflection->newInstanceArgs($arguments); |
|
|
|
} else { |
|
throw self::getBadMethodException($this, $method); |
|
} |
|
} |
|
|
|
public function __toString () |
|
{ |
|
return (string) $this->className; |
|
} |
|
|
|
private function __construct ($className) |
|
{ |
|
if (\class_exists($className, TRUE)) { |
|
$this->className = $className; |
|
|
|
} else { |
|
throw self::getClassNotFoundException($className); |
|
} |
|
} |
|
|
|
private static function initializeClassObjectInstancesForSelfClass ($selfClass) |
|
{ |
|
if (!isset(self::$classObjectInstances[$selfClass])) { |
|
self::$classObjectInstances[$selfClass] = []; |
|
} |
|
} |
|
|
|
private static function hasInstanceOfClassObject ($selfClass, $className) |
|
{ |
|
return isset(self::$classObjectInstances[$selfClass][$className]); |
|
} |
|
|
|
private static function createInstanceOfClassObject ($selfClass, $className) |
|
{ |
|
return self::$classObjectInstances[$selfClass][$className] = new $selfClass($className); |
|
} |
|
|
|
private static function retrieveInstanceOfClassObject ($selfClass, $className) |
|
{ |
|
return self::$classObjectInstances[$selfClass][$className]; |
|
} |
|
|
|
private static function getInstanceOfClassObject ($selfClass, $className) |
|
{ |
|
if (!self::hasInstanceOfClassObject($selfClass, $className)) { |
|
return self::createInstanceOfClassObject($selfClass, $className); |
|
} else { |
|
return self::retrieveInstanceOfClassObject($selfClass, $className); |
|
} |
|
} |
|
|
|
private static function getBadMethodException (ClassObject $class, $method) |
|
{ |
|
return new \BadMethodCallException(\sprintf( |
|
'Method `%s::%s` not found', |
|
$class->className, |
|
$method |
|
)); |
|
} |
|
|
|
private static function getClassNotFoundException ($className) |
|
{ |
|
return new \InvalidArgumentException(\sprintf( |
|
'Class `%s` not found for use with `%s`', |
|
$className, |
|
__CLASS__ |
|
)); |
|
} |
|
} |