Advertisement
Guest User

Untitled

a guest
Oct 9th, 2014
60
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. class Container implements ArrayAccess {
  2.  
  3.     /**
  4.      * Container bindings
  5.      * @var array
  6.      */
  7.     protected $bindings = array();
  8.  
  9.     /**
  10.      * Container instances
  11.      * @var array
  12.      */
  13.     protected $instances = array();
  14.  
  15.     /**
  16.      * Container Closures
  17.      * @var array
  18.      */
  19.     protected $closures = array();
  20.  
  21.     /**
  22.      * Maximum depth of function makeClassWithParameters
  23.      * @var int
  24.      */
  25.     protected $maxdepth = 10;
  26.  
  27.     // ================================================== //
  28.  
  29.     /**
  30.      * Public function to create new binding.
  31.      *
  32.      * @param string $key Binding name
  33.      * @param mixed $value Object to store
  34.      * @param bool $singleton Store as singleton?
  35.      * @return void
  36.      */
  37.     public function bind($key, $value, $singleton = false)
  38.     {
  39.         $this->clearBind($key);
  40.  
  41.         $this->makeBind($key, $value, (bool)$singleton);
  42.     }
  43.  
  44.     /**
  45.      * Function to get stored object or create new to store.
  46.      * If there's no stored object it will create new instance of
  47.      * class which name is $key
  48.      *
  49.      * @param string $key Binding name or class name
  50.      * @param array $parameters Parameters for new class
  51.      * @param bool $singleton Store new class as singleton?
  52.      * @return mixed
  53.      */
  54.     public function make($key, $parameters = array(), $singleton = false)
  55.     {
  56.         if($bind = $this->getBind($key))
  57.         {
  58.             if(isset($bind['type']) and $bind['type'] == 'closure')
  59.             {
  60.                 $instance = $this->closures[$key];
  61.                 $instance = $instance();
  62.  
  63.                 if(isset($bind['singleton']) and $bind['singleton'] == true)
  64.                 {
  65.                     $this->clearBind($key);
  66.  
  67.                     $this->makeBind($key, $instance, true);
  68.                 }
  69.  
  70.                 return $instance;
  71.             }
  72.             elseif(isset($bind['type']) and $bind['type'] == 'instance')
  73.             {
  74.                 return $this->instances[$key];
  75.             }
  76.  
  77.             $this->clearBind($key);
  78.             return false;
  79.         }
  80.         else
  81.         {
  82.             $instance = $this->makeClassWithParameters($key, (array)$parameters);
  83.  
  84.             if($instance != false)
  85.             {
  86.                 $this->bind($key, $instance);
  87.             }
  88.  
  89.             return $instance;
  90.         }
  91.     }
  92.  
  93.     // ================================================== //
  94.  
  95.     /**
  96.      * Creating new class with parameters.
  97.      * If new class constructor require another class as parameter
  98.      * it will be created, but max depth is limited!
  99.      *
  100.      * @throws OutOfBoundsException
  101.      * @uses ReflectionClass
  102.      *
  103.      * @param string $name Class name
  104.      * @param array $params Class parameters
  105.      * @param int $depth Depth counter
  106.      * @return mixed
  107.      */
  108.     protected function makeClassWithParameters($name, array $params, $depth = 1)
  109.     {
  110.         if($depth >= $this->maxdepth)
  111.         {
  112.             throw new OutOfBoundsException('Maximum depth of makeClassWithParameters is '.$this->maxdepth);
  113.             return false;
  114.         }
  115.  
  116.         if(class_exists($name))
  117.         {
  118.             $class = new ReflectionClass($name);
  119.  
  120.             $constructor = $class->getConstructor();
  121.  
  122.             if(!is_null($constructor) and empty($params))
  123.             {
  124.                 foreach($constructor->getParameters() as $paramdata)
  125.                 {
  126.                     $classparam = $paramdata->getClass();
  127.  
  128.                     if(is_null($classparam))
  129.                     {
  130.                         if($paramdata->isOptional())
  131.                         {
  132.                             $params[] = $paramdata->getDefaultValue();
  133.                         }
  134.                         else
  135.                         {
  136.                             $params[] = null;
  137.                         }
  138.                     }
  139.                     else
  140.                     {
  141.                         $params[] = $this->makeClassWithParameters($classparam->name, array(), $depth+1);
  142.                     }
  143.                 }
  144.             }
  145.            
  146.             return $class->newInstanceArgs($params);
  147.         }
  148.         else
  149.         {
  150.             return false;
  151.         }
  152.     }
  153.  
  154.     /**
  155.      * Getting bind if exist
  156.      *
  157.      * @return mixed
  158.      */
  159.     protected function getBind($key)
  160.     {
  161.         return isset($this->bindings[$key]) ? $this->bindings[$key] : false;
  162.     }
  163.  
  164.     /**
  165.      * Protected function to create new binding.
  166.      *
  167.      * @param string $key Binding name
  168.      * @param mixed $value Object to store
  169.      * @param bool $singleton Store as singleton?
  170.      * @return void
  171.      */
  172.     protected function makeBind($key, $value, $singleton)
  173.     {
  174.         $bind = array();
  175.  
  176.         if($value instanceof Closure)
  177.         {
  178.             $bind['type'] = 'closure';
  179.             $bind['singleton'] = (bool)$singleton;
  180.             $this->closures[$key] = $value;
  181.         }
  182.         else
  183.         {
  184.             $bind['type'] = 'instance';
  185.             $this->instances[$key] = $value;
  186.         }
  187.  
  188.         $this->bindings[$key] = $bind;
  189.     }
  190.  
  191.     /**
  192.      * Clear existing binding
  193.      *
  194.      * @param string $key Binding name
  195.      * @return void
  196.      */
  197.     protected function clearBind($key)
  198.     {
  199.         unset($this->bindings[$key], $this->instances[$key], $this->closures[$key]);
  200.     }
  201.  
  202.     // ================================================== //
  203.  
  204.     /**
  205.      * Getting container content as array
  206.      *
  207.      * @param string $key Binding name
  208.      * @return mixed
  209.      */
  210.     public function offsetGet($key)
  211.     {
  212.         return $this->make($key);
  213.     }
  214.  
  215.     /**
  216.      * Set container content as array
  217.      *
  218.      * @param string $key Binding name
  219.      * @param mixed $value Object to store
  220.      * @return void
  221.      */
  222.     public function offsetSet($key, $value)
  223.     {
  224.         if(!($value instanceof Closure))
  225.         {
  226.             $value = function() use ($value) {
  227.                 return $value;
  228.             };
  229.         }
  230.  
  231.         $this->bind($key, $value, false);
  232.     }
  233.  
  234.     /**
  235.      * Checking binding as container array
  236.      *
  237.      * @param string $key Binding name
  238.      * @return bool
  239.      */
  240.     public function offsetExists($key)
  241.     {
  242.         return isset($this->bindings[$key]);
  243.     }
  244.  
  245.     /**
  246.      * Using function unset for container as array
  247.      *
  248.      * @param string $key Binding name
  249.      * @return void
  250.      */
  251.     public function offsetUnset($key)
  252.     {
  253.         $this->clearBind($key);
  254.     }
  255.  
  256.     /**
  257.      * Magic method __get
  258.      *
  259.      * @param string $key
  260.      * @return mixed
  261.      */
  262.     public function __get($key)
  263.     {
  264.         return $this[$key];
  265.     }
  266.  
  267.     /**
  268.      * Magic method __set
  269.      *
  270.      * @param string $key
  271.      * @param mixed $value
  272.      * @return void
  273.      */
  274.     public function __set($key, $value)
  275.     {
  276.         $this[$key] = $value;
  277.     }
  278.  
  279. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement