首页 / PHP / PHP写的一个轻量级的DI容器类(转)
PHP写的一个轻量级的DI容器类(转)
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了PHP写的一个轻量级的DI容器类(转),小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3500字,纯文字阅读大概需要6分钟。
内容图文
理解什么是Di/IoC,依赖注入/控制反转。两者说的是一个东西,是当下流行的一种设计模式。大致的意思就是,准备一个盒子(容器),事先将项目中可能用到的类扔进去,在项目中直接从容器中拿,也就是避免了直接在项目中到处new,造成大量耦合。取而代之的是在项目类里面增设 setDi()和getDi()方法,通过Di同一管理类。 当然,以上内容并不是重点,详细的概念推荐参考这篇文章: http://docs.phalconphp.com/en/latest/reference/di.html 中文版: http://phalcon.5iunix.net/reference/di.html
<?php class Di implements \ArrayAccess{ private$_bindings = array();//服务列表private$_instances = array();//已经实例化的服务 //获取服务publicfunction get($name,$params=array()){ //先从已经实例化的列表中查找if(isset($this->_instances[$name])){ return$this->_instances[$name]; } //检测有没有注册该服务if(!isset($this->_bindings[$name])){ returnnull; } $concrete = $this->_bindings[$name][‘class‘];//对象具体注册内容$obj = null; //匿名函数方式if($concrete instanceof \Closure){ $obj = call_user_func_array($concrete,$params); } //字符串方式elseif(is_string($concrete)){ if(empty($params)){ $obj = new$concrete; }else{ //带参数的类实例化,使用反射$class = new \ReflectionClass($concrete); $obj = $class->newInstanceArgs($params); } } //如果是共享服务,则写入_instances列表,下次直接取回if($this->_bindings[$name][‘shared‘] == true && $obj){ $this->_instances[$name] = $obj; } return$obj; } //检测是否已经绑定publicfunction has($name){ returnisset($this->_bindings[$name]) or isset($this->_instances[$name]); } //卸载服务publicfunction remove($name){ unset($this->_bindings[$name],$this->_instances[$name]); } //设置服务publicfunction set($name,$class){ $this->_registerService($name, $class); } //设置共享服务publicfunction setShared($name,$class){ $this->_registerService($name, $class, true); } //注册服务privatefunction _registerService($name,$class,$shared=false){ $this->remove($name); if(!($class instanceof \Closure) && is_object($class)){ $this->_instances[$name] = $class; }else{ $this->_bindings[$name] = array("class"=>$class,"shared"=>$shared); } } //ArrayAccess接口,检测服务是否存在publicfunction offsetExists($offset) { return$this->has($offset); } //ArrayAccess接口,以$di[$name]方式获取服务publicfunction offsetGet($offset) { return$this->get($offset); } //ArrayAccess接口,以$di[$name]=$value方式注册服务,非共享publicfunction offsetSet($offset, $value) { return$this->set($offset,$value); } //ArrayAccess接口,以unset($di[$name])方式卸载服务publicfunction offsetUnset($offset) { return$this->remove($offset); } }
演示:
<?php header("Content-Type:text/html;charset=utf8"); class A{ public$name; public$age; publicfunction __construct($name=""){ $this->name = $name; } } include "Di.class.php"; $di = new Di(); //匿名函数方式注册一个名为a1的服务$di->setShared(‘a1‘,function($name=""){ returnnew A($name); }); //直接以类名方式注册$di->set(‘a2‘,‘A‘); //直接传入实例化的对象$di->set(‘a3‘,new A("小唐")); $a1 = $di->get(‘a1‘,array("小李")); echo$a1->name."<br/>";//小李$a1_1 = $di->get(‘a1‘,array("小王")); echo$a1->name."<br/>";//小李echo$a1_1->name."<br/>";//小李$a2 = $di->get(‘a2‘,array("小张")); echo$a2->name."<br/>";//小张$a2_1 = $di->get(‘a2‘,array("小徐")); echo$a2->name."<br/>";//小张echo$a2_1->name."<br/>";//小徐$a3 = $di[‘a3‘];//可以直接通过数组方式获取服务对象echo$a3->name."<br/>";//小唐
通过set和setShared方式注册服务,支持 匿名函数,类名字符串,已经实例化的对象,两者的区别是:
set方式注册的,每次获取的时候都会重新实例化
setShared方式的,则只实例化一次,也就是所谓的单例模式
当然,对于直接注册已经实例化的对象,如上代码中的a3服务,set和setShared效果是一样的。
通过$di->get()获取服务,可接受两个参数,第一个参数是服务名,比如a1,a2,a3是必须的,第二个参数是一个数组,第二个参数会被当作匿名函数中的参数或者类构造函数里的参数传进去,参考call_user_func_array()。
删除服务则可以通过
unset($di[‘a1‘]);
or
$di->remove(‘a1‘);
判断是否包含一个服务可以通过
isset($di[‘a1‘]);
or
$di->has(‘a1‘);
原文:http://www.cnblogs.com/hubing/p/5222596.html
内容总结
以上是互联网集市为您收集整理的PHP写的一个轻量级的DI容器类(转)全部内容,希望文章能够帮你解决PHP写的一个轻量级的DI容器类(转)所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。