这里有新鲜出炉的 YII 2.0 教程,程序狗速度看过来!
Yii Framework 是一个基于组件、用于开发大型 web 应用的高性能 PHP 框架。Yii 提供了今日 Web 2.0 应用开发所需要的几乎一切功能。Yii 是最有效率的 PHP 框架之一。Yii 是创始人薛强的心血结晶,于 2008 年 1 月 1 日开始开发。
这篇文章主要介绍了 Yii 框架组件和事件行为管理, 详细分析了 Yii 框架组件管理与行为管理的原理与使用技巧, 需要的朋友可以参考下
本文实例讲述了 Yii 框架组件和事件行为管理。分享给大家供大家参考,具体如下:
Yii 是一个基于组件、用于开发大型 Web 应用的高性能 PHP 框架。CComponent 几乎是所有类的基类,它控制着组件与事件的管理,其方法与属性如下,私有变量 $_e 数据存放事件 (evnet,有些地方叫 hook),$_m 数组存放行为 (behavior)。
组件管理
YII 是一个纯 oop 框架,很多类中的成员变量的受保护或者私有的,CComponent 中利用 php 中的魔术方法__get(),__set() 来访问和设置属性,但这些方法的作用远不指这些。下面用__get() 来说明
- public function __get($name)
- {
- $getter='get'.$name;
- if(method_exists($this,$getter))
- return $this->$getter();
- else if(strncasecmp($name,'on',2)===0 && method_exists($this,$name))
- {
- // duplicating getEventHandlers() here for performance
- $name=strtolower($name);
- if(!isset($this->_e[$name]))
- $this->_e[$name]=new CList;
- return $this->_e[$name];
- }
- else if(isset($this->_m[$name]))
- return $this->_m[$name];
- else if(is_array($this->_m))
- {
- foreach($this->_m as $object)
- {
- if($object->getEnabled() && (property_exists($object,$name) || $object->canGetProperty($name)))
- return $object->$name;
- }
- }
- throw new CException(Yii::t('yii','Property "{class}.{property}" is not defined.',
- array('{class}'=>get_class($this), '{property}'=>$name)));
- }
当 CComponent 或者其子类对象实例 $obj->name 的时候,__get($name) 方法:
1、首先判断实例中是否有 getName() 方法,如果有则返回 ,如果没有执行第 2 步
2、判断是否是以 on 开头的,以 on 开头的一般都是 CComponent 子类中预留的事件,用与挂在事件,通过 method_exists($this,$name) 判断该 name 是否存在类的实例中,如果存在,返回事件,否则执行第 3 步
3、如果 name 存在行为数组中,返回改行为,如果不存在,执行第 4 步
4、遍历行为数组,数组中行为是 CBehavior 子类的实例,而 CBehavior 又是 CComponent 中子类,所以用递归的方法获取行为中的方法,如果没有,执行第 5 步
5、抛出异常:请求的属性不存在。
在 CComponent 子类中可以重载__get() 方法,如在 CModule 中加入了获取组件的判断。这就注意一个问题了属性和组件名最好不要重名,因为程序会优先加载组件,可能得到的不是我们想要的属性,如果必须重名的话,就要用 getter 获取属性。
- public function __get($name)
- {
- if($this->hasComponent($name))
- return $this->getComponent($name);
- else
- return parent::__get($name);
- }
关于组件的加载与创建,上篇 YII 框架分析笔记 1:YII 执行流程中的第 3 点中有个疑问:注册框架核心组件的时候一下子加载这么多,是不是影响性能呢?其实没有,注册的时候只是把组件和其对应的配置用键值对的形式保存在数组中(预加载的除外),当用到时候才像上面那样去创建组件,会通过 YIIBase 中的 createComponent()方法创建,并初始化。通过 CModule 或其子孙类 (如 CWebApplication) 调用__get()或 getComponent()获取组件时,CModule 通过 $_components 数组建立对象池,确保每个组件在一次请求中只实例化一次。
事件行为管理
事件相当于对一个组件的扩展或者插件,以组件中预留的钩子实现组件内部调用外部、外部对组件部分控制。在 CComponent 子类中可以定义以 on 开头的方法为事件,类似于 js 中的 onclick、onchange 等,其实原理差不多。所有事件是与 CComponent 在同一文件中 CEvent 的子类。
- /**
- * Raised right BEFORE the application processes the request.
- * @param CEvent $event the event parameter
- */
- public function onBeginRequest($event)
- {
- $this->raiseEvent('onBeginRequest',$event);
- }
- /**
- * Runs the application.
- * This method loads static application components. Derived classes usually overrides this
- * method to do more application-specific tasks.
- * Remember to call the parent implementation so that static application components are loaded.
- */
- public function run()
- {
- if($this->hasEventHandler('onBeginRequest'))
- $this->onBeginRequest(new CEvent($this));
- $this->processRequest();
- if($this->hasEventHandler('onEndRequest'))
- $this->onEndRequest(new CEvent($this));
- }
比如在 CApplication 中调用 run() 方法在处理请求之前先判断外部是否传人 onBeginRequest 事件的句柄,如果有则通过 onBeginRequest($event) 方法调用 CComponent 中的 raiseEvent() 方法执行句柄中的函数或者方法。
行为是事件的升级版,所有的行为都是 CBehavior 的子类。分析上面的__get() 方法分析第 4 步可以看出来行为的作用是完全扩展组件的特性,可以是属性、方法、事件甚至行为,这样使程序开发更加灵活。
行为的另一个作用是将相似事件句柄放在一起,在行为执行 attach() 方法的时候会将 events() 方法中返回的事件句柄绑定,这样做达到方面管理和扩展的目的。比如 CModelBehavior 中将 model 相关的事件集中起来,便于其子类的复用,当我们需求为 model 添加行为的时候可以继承它。
PS: 小编在这里推荐一款本站的 php 格式化美化的排版工具帮助大家在以后的 PHP 程序设计中进行代码排版:
希望本文所述对大家基于 Yii 框架的 PHP 程序设计有所帮助。
来源: http://www.phperz.com/article/17/0828/343635.html