* // Get the active container instance * $container = IoC::container(); * * // Get the active container instance and call the resolve method * $container = IoC::container()->resolve('instance'); * * * @return Container */ public static function container() { return static::$container; } /** * Magic Method for calling methods on the active container instance. * * * // Call the "resolve" method on the active container instance * $instance = IoC::resolve('instance'); * * // Equivalent operation using the "container" method * $instance = IoC::container()->resolve('instance'); * */ public static function __callStatic($method, $parameters) { return call_user_func_array(array(static::$container, $method), $parameters); } } class Container { /** * The resolved singleton instances. * * @var array */ public $singletons = array(); /** * The registered dependencies. * * @var array */ protected $registry = array(); /** * Create a new IoC container instance. * * @param array $registry * @return void */ public function __construct($registry = array()) { $this->registry = $registry; } /** * Register an object and its resolver. * * The resolver function is called when the registered object is requested. * * * // Register an object in the container * IoC::register('something', function($container) {return new Something;}); * * // Register an object in the container as a singleton * IoC::register('something', function($container) {return new Something;}, true); * * * @param string $name * @param Closure $resolver * @return void */ public function register($name, $resolver, $singleton = false) { $this->registry[$name] = array('resolver' => $resolver, 'singleton' => $singleton); } /** * Determine if an object has been registered in the container. * * @param string $name * @return bool */ public function registered($name) { return array_key_exists($name, $this->registry); } /** * Register an object as a singleton. * * Singletons will only be instantiated the first time they are resolved. On subsequent * requests for the object, the original instance will be returned. * * * // Register an object in the container as a singleton * IoC::singleton('something', function($container) {return new Something;}); * * * @param string $name * @param Closure $resolver * @return void */ public function singleton($name, $resolver) { $this->register($name, $resolver, true); } /** * Register an instance as a singleton. * * This method allows you to register an already existing object instance with the * container to be managed as a singleton instance. * * * // Register an instance with the IoC container * IoC::instance('something', new Something); * * * @param string $name * @param mixed $instance * @return void */ public function instance($name, $instance) { $this->singletons[$name] = $instance; } /** * Resolve an object. * * The object's resolver will be called and its result will be returned. If the * object is registered as a singleton and has already been resolved, the instance * that has already been instantiated will be returned. * * * // Get the "something" object out of the IoC container * $something = IoC::resolve('something'); * * * @param string $name * @return mixed */ public function resolve($name) { if (array_key_exists($name, $this->singletons)) return $this->singletons[$name]; if ( ! $this->registered($name)) { throw new \Exception("Error resolving [$name]. No resolver has been registered in the container."); } $object = call_user_func($this->registry[$name]['resolver'], $this); return (isset($this->registry[$name]['singleton'])) ? $this->singletons[$name] = $object : $object; } /** * Magic Method for resolving classes out of the IoC container. * * * // Get the "something" instance out of the IoC container * $something = IoC::container()->something; * * // Equivalent method of retrieving the instance using the resolve method * $something = IoC::container()->resolve('something'); * */ public function __get($key) { if ($this->registered($key)) return $this->resolve($key); throw new \Exception("Attempting to resolve undefined class [$key]."); } }