Advertisement
Guest User

Untitled

a guest
Oct 8th, 2014
52
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 5.56 KB | None | 0 0
  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.                 $constructor = $constructor->getParameters();
  125.  
  126.                 foreach($constructor as $classparam)
  127.                 {
  128.                     $classparam = $classparam->getClass();
  129.  
  130.                     if(is_null($classparam))
  131.                     {
  132.                         $params[] = null;
  133.                     }
  134.                     else
  135.                     {
  136.                         $params[] = $this->makeClassWithParameters($classparam->name, array(), $depth+1);
  137.                     }
  138.                 }
  139.  
  140.                 $class = $class->newInstanceArgs($params);
  141.             }
  142.             else
  143.             {
  144.                 $class = $class->newInstanceArgs($params);
  145.             }
  146.  
  147.             return $class;
  148.         }
  149.         else
  150.         {
  151.             return false;
  152.         }
  153.     }
  154.  
  155.     /**
  156.      * Getting bind if exist
  157.      *
  158.      * @return mixed
  159.      */
  160.     protected function getBind($key)
  161.     {
  162.         return isset($this->bindings[$key]) ? $this->bindings[$key] : false;
  163.     }
  164.  
  165.     /**
  166.      * Protected function to create new binding.
  167.      *
  168.      * @param string $key Binding name
  169.      * @param mixed $value Object to store
  170.      * @param bool $singleton Store as singleton?
  171.      * @return void
  172.      */
  173.     protected function makeBind($key, $value, $singleton)
  174.     {
  175.         $bind = array();
  176.  
  177.         if($value instanceof Closure)
  178.         {
  179.             $bind['type'] = 'closure';
  180.             $bind['singleton'] = (bool)$singleton;
  181.             $this->closures[$key] = $value;
  182.         }
  183.         else
  184.         {
  185.             $bind['type'] = 'instance';
  186.             $this->instances[$key] = $value;
  187.         }
  188.  
  189.         $this->bindings[$key] = $bind;
  190.     }
  191.  
  192.     /**
  193.      * Clear existing binding
  194.      *
  195.      * @param string $key Binding name
  196.      * @return void
  197.      */
  198.     protected function clearBind($key)
  199.     {
  200.         unset($this->bindings[$key], $this->instances[$key], $this->closures[$key]);
  201.     }
  202.  
  203.     // ================================================== //
  204.  
  205.     /**
  206.      * Getting container content as array
  207.      *
  208.      * @param string $key Binding name
  209.      * @return mixed
  210.      */
  211.     public function offsetGet($key)
  212.     {
  213.         return $this->make($key);
  214.     }
  215.  
  216.     /**
  217.      * Set container content as array
  218.      *
  219.      * @param string $key Binding name
  220.      * @param mixed $value Object to store
  221.      * @return void
  222.      */
  223.     public function offsetSet($key, $value)
  224.     {
  225.         if(!($value instanceof Closure))
  226.         {
  227.             $value = function() use ($value) {
  228.                 return $value;
  229.             };
  230.         }
  231.  
  232.         $this->bind($key, $value, false);
  233.     }
  234.  
  235.     /**
  236.      * Checking binding as container array
  237.      *
  238.      * @param string $key Binding name
  239.      * @return bool
  240.      */
  241.     public function offsetExists($key)
  242.     {
  243.         return isset($this->bindings[$key]);
  244.     }
  245.  
  246.     /**
  247.      * Using function unset for container as array
  248.      *
  249.      * @param string $key Binding name
  250.      * @return void
  251.      */
  252.     public function offsetUnset($key)
  253.     {
  254.         $this->clearBind($key);
  255.     }
  256.  
  257.     /**
  258.      * Magic method __get
  259.      *
  260.      * @param string $key
  261.      * @return mixed
  262.      */
  263.     public function __get($key)
  264.     {
  265.         return $this[$key];
  266.     }
  267.  
  268.     /**
  269.      * Magic method __set
  270.      *
  271.      * @param string $key
  272.      * @param mixed $value
  273.      * @return void
  274.      */
  275.     public function __set($key, $value)
  276.     {
  277.         $this[$key] = $value;
  278.     }
  279.  
  280. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement