Yii框架核心组件类实例详解


Posted in PHP onAugust 06, 2019

本文实例讲述了Yii框架核心组件类。分享给大家供大家参考,具体如下:

CComponent类为YII框架的基于组件和事件驱动编程提供了基础,YII框架中的大部分类都将CComponent类作为基类。

CComponent类为它的子类提供3个特性:

1、成员变量扩展

通过定义两个成员函数(getXXX/setXXX)来定义一个成员变量,比如:

public function getText() {…}
public function setText {…}

这样就相当于定义了一个$text成员变量,可以这样调用

$a=new CComponent;
$a=$component->text; // 等价于$a=$component->getText();
$component->text='abc'; // 等价于$component->setText(‘abc');

CComponent是通过魔术方法__get和__set来实现“成员变量扩展”特性的,如果对类本身不存在的成员变量进行操作时,php会调用这个类 的__get和__set方法来进行处理。CComponent利用这两个魔术方法实现了“成员变量扩展”特性。下图描述了一个CComponent的子 类,它增加了active和sessionName两个成员变量,该图描述了对于这两个成员变量的调用流程。

Yii框架核心组件类实例详解

面向对象编程中直接定义一个成员变量就可以了,为什么CComponent要通过定义2个函数来实现一个成员变量呢?一个主要得原因是需要对成员变 量进行“延时加载”,一般情况下类的成员变量是在构造函数或者初始化函数进行统一赋值,但是在一次web请求的处理过程中不是每个成员变量都会被使用,比 如App类中定义了两个成员变量:$cache和$db($cache是一个缓存对象,$db是一个数据库链接对象),这两个对象在App类初始化的时候 创建,但是一个web网站的有些页面,它内容可以通过缓存获取,那么数据库链接对象其实就不需要创建。如果将App定义为CComponent的子类,在 App类中定义两个方法:getCache/getDb,这样就可以做到第一次使用db成员变量的时候,才调用getDb函数来进行数据库链接的初始化, 从而实现延时加载——即在第一次使用时进行初始化。虽然延时加载会增加一次函数调用,但是可以减少不必要的成员变量的初始化(总体上其实是提升了网站的访 问速度),而且可以使得我们的代码更加易维护、易扩展。

延时加载应该是“成员变量扩展”特性的最重要的用途,当然这个特性还会有其它用途,想一想,当你操作一个成员变量的时候,你其实是在调用getXXX和setXXX成员函数,你是在调用一段代码!

2、事件模型

事件模型就是设计模式中的“观察者模式”:当对象的状态发生了变化,那么这个对象可以将该事件通知其它对象。

为了使用事件模型,需要实现这三个步骤:1、定义事件;2、注册事件句柄;3、触发事件。
CComponent的子类通过定义一个以on打头的成员函数来定义一个事件,比如:public function onClick(){…},接着通过调用attachEventHandler成员函数来注册事件句柄(可以注册多个事件句柄),最后通过调用 raiseEvent来触发事件。

CComponent类使用一个私有的成员变量来保存事件以及处理该事件的所有句柄,该成员变量可以看作一个hash表,hash表的key是事件的名称,hash表的value是事件处理函数链表。

Yii框架核心组件类实例详解

3、行为类绑定

有两种办法可以对类添加特性:1、直接修改这个类的代码,添加一些成员函数和成员变量;2、派生,通过子类来扩展。很明显第二种方法更加易维护、易扩展。如果需要对一个类添加多个特性(多人在不同时期),那么需要进行多级派生,这显然加大了维护成本。

CComponent使用一种特殊的方式对类信息扩展——行为类绑定。行为类是一个CBehavior的子类,CComponent可以将一个或者多个 CBehavior类的成员函数和成员变量添加到自己身上,并且在不需要的时候卸载掉某些CBehavior类。下面是一个简单的例子:

//计算器类
class Calculator extends CBehavior
{
public function add($x, $y) { return $x + $y; }
public function sub($x, $y) { return $x ? $y; }
…
}
$comp = new CComponent();
//为我的类添加计算器功能
$comp->attachbehavior(‘calculator', new Calculator());
$comp->add(2, 5);
$comp->sub(2, 5);

CComponent通过__get、__set和__call这3个魔术方法来实现“行为类绑定”这个特性,当调用CComponent类不存在的成员 变量和成员方法的时候,CComponent类会通过这三个魔法方法在“动态绑定的行为对象”上进行查找。即将不存在的成员变量和成员方法路由到“动态绑 定对象”上。

Yii框架核心组件类实例详解

可以用3句话来总结CComponent类的特性:

1、 更好的配置一个对象,当设置对象的成员变量的时候,其实是运行一段代码;
2、 更好的监听一个对象,当对象的内部状态发生变化的时候,其它对象可以得到通知;
3、 更好的扩展一个对象,可以给一个对象增加成员变量和成员函数,还能监听这个对象的状态。

希望本文所述对大家基于Yii框架的PHP程序设计有所帮助。

PHP 相关文章推荐
用php来检测proxy
Oct 09 PHP
让Nginx支持ThinkPHP的URL重写和PATHINFO的方法分享
Aug 08 PHP
ThinkPHP使用UTFWry地址库进行IP定位实例
Apr 01 PHP
php网站被挂木马后的修复方法总结
Nov 06 PHP
php实现计数器方法小结
Jan 05 PHP
解决nginx不支持thinkphp中pathinfo的问题
Jul 21 PHP
完美利用Yii2微信后台开发的系列总结
Jul 18 PHP
PHP利用超级全局变量$_GET来接收表单数据的实例
Nov 05 PHP
Laravel框架中VerifyCsrfToken报错问题的解决
Aug 30 PHP
ThinkPHP5.0框架控制器继承基类和自定义类示例
May 25 PHP
Laravel框架生命周期与原理分析
Jun 12 PHP
Thinkphp 框架扩展之类库扩展操作详解
Apr 23 PHP
PHP使用Session实现上传进度功能详解
Aug 06 #PHP
PHP使用ajax的post方式下载excel文件简单示例
Aug 06 #PHP
PHP中的自动加载操作实现方法详解
Aug 06 #PHP
Thinkphp自定义生成缩略图尺寸的方法
Aug 05 #PHP
thinkphp5.1框架中容器(Container)和门面(Facade)的实现方法分析
Aug 05 #PHP
RSA实现JS前端加密与PHP后端解密功能示例
Aug 05 #PHP
thinkPHP5框架接口写法简单示例
Aug 05 #PHP
You might like
超强分页类2.0发布,支持自定义风格,默认4种显示模式
2007/01/02 PHP
PHP生成plist数据的方法
2015/06/16 PHP
[原创]PHP字符串中插入子字符串方法总结
2016/05/06 PHP
PHP bin2hex()函数基础实例讲解
2019/02/11 PHP
laravel框架路由分组,中间件,命名空间,子域名,路由前缀实例分析
2020/02/18 PHP
greybox——不开新窗口看新的网页
2007/02/20 Javascript
HTML代码中标签的全部属性 中文注释说明
2009/03/26 Javascript
JQuery实现的在新窗口打开链接的方法小结
2010/04/22 Javascript
关于JAVASCRIPT urldecode URL解码的问题
2012/01/08 Javascript
jQuery表单验证插件formValidator(改进版)
2012/02/03 Javascript
原生js结合html5制作小飞龙的简易跳球
2015/03/30 Javascript
Three.js学习之Lamber材质和Phong材质
2016/08/04 Javascript
js获取页面引用的css样式表中的属性值方法(推荐)
2016/08/19 Javascript
Angularjs实现mvvm式的选项卡示例代码
2016/09/08 Javascript
原生js开发的日历插件
2017/02/04 Javascript
node+koa实现数据mock接口的方法
2017/09/20 Javascript
React Native开发封装Toast与加载Loading组件示例
2018/09/08 Javascript
微信小程序自定义tabBar的踩坑实践记录
2020/11/06 Javascript
[50:17]Newbee vs Serenity 2018国际邀请赛小组赛BO2 第二场 8.17
2018/08/18 DOTA
[01:03:33]Alliance vs TNC 2019国际邀请赛小组赛 BO2 第一场 8.16
2019/08/18 DOTA
python实现保存网页到本地示例
2014/03/16 Python
从零学python系列之新版本导入httplib模块报ImportError解决方案
2014/05/23 Python
全面解析Python的While循环语句的使用方法
2015/10/13 Python
解决项目pycharm能运行,在终端却无法运行的问题
2019/01/19 Python
python修改文件内容的3种方法详解
2019/11/15 Python
keras实现调用自己训练的模型,并去掉全连接层
2020/06/09 Python
Python request post上传文件常见要点
2020/11/20 Python
澳大利亚吉他在线:Artist Guitars
2017/03/30 全球购物
幼儿园保教管理制度
2014/02/03 职场文书
分公司经理任命书
2014/06/05 职场文书
最美家庭活动方案
2014/08/31 职场文书
个人先进材料范文
2014/12/30 职场文书
暑期实践个人总结
2015/03/06 职场文书
2015公务员年度考核评语
2015/03/25 职场文书
2015年乡镇扶贫工作总结
2015/04/08 职场文书
公司开业主持词
2015/07/02 职场文书