Di.php 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. <?php
  2. //decode by http://www.yunlu99.com/
  3. namespace System;
  4. class Di implements \ArrayAccess{
  5. private $_bindings = array();//服务列表
  6. private $_instances = array();//已经实例化的服务
  7. //获取服务
  8. public function get($name,$params=array()){
  9. //先从已经实例化的列表中查找
  10. if(isset($this->_instances[$name])){
  11. return $this->_instances[$name];
  12. }
  13. //检测有没有注册该服务
  14. if(!isset($this->_bindings[$name])){
  15. return null;
  16. }
  17. $concrete = $this->_bindings[$name]['class'];//对象具体注册内容
  18. $obj = null;
  19. //匿名函数方式
  20. if($concrete instanceof \Closure){
  21. $obj = call_user_func_array($concrete,$params);
  22. }
  23. //字符串方式
  24. elseif(is_string($concrete)){
  25. if(empty($params)){
  26. $obj = new $concrete;
  27. }else{
  28. //带参数的类实例化,使用反射
  29. $class = new \ReflectionClass($concrete);
  30. $obj = $class->newInstanceArgs($params);
  31. }
  32. }
  33. //如果是共享服务,则写入_instances列表,下次直接取回
  34. if($this->_bindings[$name]['shared'] == true && $obj){
  35. $this->_instances[$name] = $obj;
  36. }
  37. return $obj;
  38. }
  39. //检测是否已经绑定
  40. public function has($name){
  41. return isset($this->_bindings[$name]) or isset($this->_instances[$name]);
  42. }
  43. //卸载服务
  44. public function remove($name){
  45. unset($this->_bindings[$name],$this->_instances[$name]);
  46. }
  47. //设置服务
  48. public function set($name,$class){
  49. $this->_registerService($name, $class);
  50. }
  51. //设置共享服务
  52. public function shared($name,$class){
  53. $this->_registerService($name, $class, true);
  54. }
  55. //注册服务
  56. private function _registerService($name,$class,$shared=false){
  57. if(!($class instanceof \Closure) && is_object($class)){
  58. $this->_instances[$name] = $class;
  59. }else{
  60. $this->_bindings[$name] = array("class"=>$class,"shared"=>$shared);
  61. }
  62. }
  63. //ArrayAccess接口,检测服务是否存在
  64. public function offsetExists($offset) {
  65. return $this->has($offset);
  66. }
  67. //ArrayAccess接口,以$di[$name]方式获取服务
  68. public function offsetGet($offset) {
  69. return $this->get($offset);
  70. }
  71. //ArrayAccess接口,以$di[$name]=$value方式注册服务,非共享
  72. public function offsetSet($offset, $value) {
  73. return $this->set($offset,$value);
  74. }
  75. //ArrayAccess接口,以unset($di[$name])方式卸载服务
  76. public function offsetUnset($offset) {
  77. return $this->remove($offset);
  78. }
  79. }