Yii2 实例管理
来源:互联网 发布:公司logo设计软件 编辑:程序博客网 时间:2024/05/20 11:27
Yii2 实例管理
Yii2框架没有提供类似ZendFramework3中提供的ServiceManager.那么Yii2框架是如何管理对象实例的呢?
长时间使用Yii2框架的童鞋一定已经适应了对象中的public变量,以及一个来自yii\base\Component的__set()魔术方法来完成对象构造的过程,但是新鸟如何使用这一切来实例化一个对象呢?
Yii2最擅长的是extends多个对象使他们拥有多个父类的特征.那么习惯了ZendFramework3这种纯粹OOP的童鞋,有没有方法既可以尽快适应Yii2的简约,又坚定的不侵犯对象变量的私有性,甚至还能优雅的用注入取代继承呢?
以下比较对象默认为ZendFramework3.
Yii2 对象的实例化
在ZendFramework3中,对象的实例化是我见过相对复杂的.
- 首先ServiceManager会读取所有已配置模块的Module对象(每个模块提供给ServiceManager的入口),并根据loadModules,loadModule等事件,以特定(可配置的,通过引用不同的内置Interface)方式获取模块配置文件.
- 获得配置文件时,ServiceManager会检查依赖(如果需要).
- 一切顺利后,ServiceManager会依照配置文件,寻找这个模块或类的工厂.工厂是一个callable,可以极其复杂,因为每个工厂会接受到整个项目的容器,也就是ServiceManager,也可以是简单的内置,InvokeFactory.
- 最终ServiceManager会自动的将工厂的产品,也就是这个模块的实例缓存到自身的变量中,以便全局可以访问.
可见ServiceManager是一个综合体,用于对象实例的管理,充当全局容器(里面甚至包含所有的配置文件和事件管理模块等所有框架的内核).
你肯定会担心性能损耗,在小型项目中这种损耗是有的,就像快速排序,面对大宗数据才是它大展身手的时候.也就是说,随着项目体量的增加,这种损耗的递增会远远低于体量的递增.
缺点:学习成本很高.
那么Yii2中有这样的机制吗?答曰,有.
Yii2中居然用一个近似让人啼笑皆非的方式解决了这个全局容器的需求.就是那个哪里都能看到的静态调用Yii.
use Yii;
很聪明!但是缺少了保障:
安全性.对于全部项目,Yii这个容器始终是可见的,没有注入的安全性,不注入你休想碰全局.Yii2的问题在于安全,尤其是多人开发的项目,例如通过
Yii::$app->user->setIdentity($identity);
轻松改变框架的当前登录用户,伪造当前用户.稳定性.这个是我的猜测,将整个框架直接交给一个Yii,真的好吗?做法等同于将整个框架放入了一个PHP数组,并且这还是个全局的数组.
优点:学习成本很低.
Yii2在设计上表达了一个简单粗暴的观点,简单大于一切,甚至性能!
Yii2在对象的实例化时居然使用了Reflection[泪目.jpg],你没有看错,就是那个性能如老狗的反射.为什么呢?
就为了让你少些代码.
Yii::createObject([ 'class' => 'foo\bar', 'name' => 'Bob']);
以上代码实例化了一个foo\bar;对象,并执行了$bar->name = 'Bob';
,怎么样,是不是很简单?这一切都是Reflection的功劳.当然Yii::createObject()
还有一下用法,更加神奇.
//In foo/bar.phpclass bar{ public function __construct(SomeInterface $param1, $param2 = 'nothing') { //something to do. }}//In some place.Yii::createObject('foo\bar', [ 'param1' => $someClass,//instance from SomeInterface])
可见.Yii::createObject()
还可以对你的__construct
赋值.不但会检查参数列表的默认值,对象类型,而且还会为提供可变参数的构造函数检查PHP’版本.很贴心有木有?
但是这一切都是Reflection提供的.也是在PHP应用层能解决的唯一途径.
在动不动就实例化几百个对象的应用中,如果追求性能极致的小伙伴,最好还是自己实现实例管理工具.我也会在后续的空闲时间实现这个功能,请关注本人GitHub.
Yii2 对象实例的缓存
var_dump(Yii::$container->get(Test::class) === Yii::$container->get(Test::class));
上例返回false
[懵逼.jpg],怎么回事,Yii2不缓存对象吗?那么Yii2的单例如何实现呢?
原来,Yii2中你要想让自己的对象被缓存,只有先Yii::$container->set()
,再Yii::$container->get()
.set
和get
的参数列表是对称的.
也就是说,Yii2不会自动给你缓存对象,实现单例.可能是怕误导不知道设计模式的初学者,为了对新手友好吧.
set
和get
的具体用法在\yii\di\Container
的注释中有非诚详细的说明.
值得一说的是,作者也意识到频繁的使用Reflection对性能的影响,所以在每次实例化的时候会自动的缓存对象的Reflection.这点还是非常温馨的.
Yii2中最常见的实例化对象的方法
Yii::createObject();
这个东西,这其实只是简单的对yii\di\Containre
的get()
的封装.
这个方法有两个参数:
- 对象设置
这是个数组,除了'class' => 'SomeClass'
表示这个类的名字外,其他全部代表这个类的属性. - constructor参数列表
这个没有什么好解释的,就是构造函数的参数列表写成数组的形式而已.
总结
其实作文还没有写完,我并没有去yy怎样去自己实现一个实例容器模块.因为我想在模块出现在GitHub上的时候,结合README详细说明.并在以后的开发中不断改进.
毫无疑问,Yii2是个非常精妙的框架,脾气也非常清晰,易用大于一切,毕竟用框架开发的项目不会是超大项目.如果追求性能上的极致,可能任何框架都没法满足你的要求,甚至是PHP本身.到那时候的讨论可能涉及到更深的层次.就目前而言,就目前的应用层次,看待每一个框架,你会发现每个作者的思想都有很独特的地方,可能这个思想本身就已经大于框架本身的意义了,尤其是每个作者展现给我们的,在现实和理想冲突的时候,做出的妥协.
- Yii2 实例管理
- Yii2 模型实例化
- yii2入门实例
- Yii2 菜单menu管理
- yii2权限管理
- yii2-rbac及yii2-admin可视化管理
- yii2 restful api搭建 实例
- yii2 restful api搭建 实例
- YII2框架RBAC 实例运用
- Yii2权限管理之ACF
- yii2高级模板借助于yii2-admin&yii2-adminlte-asset的RBAC权限管理
- Yii2 使用 RESTful 写API接口 实例
- yii2无限分类实例-非数据库递归
- Yii2 使用 RESTful 写API接口 实例
- Yii2实例化Model[两种方法]
- Yii2-admin RBAC权限管理的实现
- Yii2-admin RBAC权限管理的实现
- Yii2-rbac权限基础--菜单menu管理
- bzoj1055 [HAOI2008]玩具取名
- Oracle插入带序列id的数据
- 求大家别秀智商了:请给我的头像一顶圣诞帽@微信官方
- linux快捷操作
- 均数间的多重比较的方法的选择【转载】
- Yii2 实例管理
- Android asmack使用介绍
- 拓扑排序
- AI从业者需要应用的10种深度学习方法
- 用C语言开发一个BT下载软件(一) ------ BitTorrent协议 -1
- CentOS7 Shell脚本基础及补充
- [LeetCode] 199. Binary Tree Right Side View
- 在openwrt里面增加开机自启动程序
- Eclipse通过EGit插件提交多个项目到同一个仓库