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教程 变量定义
Oct 23 PHP
PHP中PDO的错误处理
Sep 04 PHP
PHP中文分词 自动获取关键词介绍
Nov 13 PHP
php中使用__autoload()自动加载未定义类的实现代码
Feb 06 PHP
php cli 小技巧
Jun 03 PHP
ThinkPHP表单自动提交验证实例教程
Jul 18 PHP
Zend Framework教程之前端控制器Zend_Controller_Front用法详解
Mar 07 PHP
Thinkphp批量更新数据的方法汇总
Jun 29 PHP
PHP在innodb引擎下快速代建全文搜索功能简明教程【基于xunsearch】
Oct 14 PHP
yii框架搜索分页modle写法
Dec 19 PHP
php中遍历二维数组并以表格的形式输出的方法
Jan 03 PHP
PHP高并发和大流量解决方案整理
Mar 09 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
用PHP函数解决SQL injection
2006/10/09 PHP
PHP简单实现HTTP和HTTPS跨域共享session解决办法
2015/05/27 PHP
学习php设计模式 php实现建造者模式
2015/12/07 PHP
PHP实现在数据库百万条数据中随机获取20条记录的方法
2017/04/19 PHP
JavaScript修改css样式style
2008/04/15 Javascript
使用滤镜设置透明导致 IE 6/7/8/9 解析异常的解决方法
2011/04/07 Javascript
gridpanel动态加载数据的实例代码
2013/07/18 Javascript
jquery ready函数、css函数及text()使用示例
2013/09/27 Javascript
jQuery取得select选择的文本与值的示例
2013/12/09 Javascript
jQuery动态修改超链接地址的方法
2015/02/13 Javascript
基于JavaScript如何实现私有成员的语法特征及私有成员的实现方式
2015/10/28 Javascript
javascript显示倒计时控制按钮的简单实现
2016/06/07 Javascript
Javascript类型系统之String字符串类型详解
2016/06/21 Javascript
vue input实现点击按钮文字增删功能示例
2019/01/29 Javascript
JavaScript面试技巧之数组的一些不low操作
2019/03/22 Javascript
jQuery-Citys省市区三级菜单联动插件使用详解
2019/07/26 jQuery
node.js域名解析实现方法详解
2019/11/05 Javascript
基于jquery实现彩色投票进度条代码解析
2020/08/26 jQuery
python使用装饰器和线程限制函数执行时间的方法
2015/04/18 Python
python使用socket进行简单网络连接的方法
2015/04/29 Python
Python中的is和==比较两个对象的两种方法
2017/09/06 Python
Ubuntu下使用python读取doc和docx文档的内容方法
2018/05/08 Python
numpy linalg模块的具体使用方法
2019/05/26 Python
Django模型修改及数据迁移实现解析
2019/08/01 Python
python英语单词测试小程序代码实例
2019/09/09 Python
详解python metaclass(元类)
2020/08/13 Python
Amaze UI 文件选择域的示例代码
2020/08/26 HTML / CSS
塔吉特百货公司官网:Target
2017/04/27 全球购物
《草原》教学反思
2014/02/15 职场文书
幼儿园教师教育感言
2014/02/28 职场文书
《故乡》教学反思
2014/04/10 职场文书
工地安全生产标语
2014/06/06 职场文书
大学生就业求职信
2014/06/12 职场文书
公司合作协议范文
2014/10/01 职场文书
关于感恩的歌曲整理(8首)
2019/08/14 职场文书
Nginx URL重写rewrite机制原理及使用实例
2021/04/01 Servers