Yii Framework框架中事件和行为的区别及应用实例分析

这篇文章主要介绍了Yii Framework框架中事件和行为的区别及应用,结合实例形式分析了Yii Framework框架中事件和行为的相关概念、原理、区别及应用操作技巧,需要的朋友可以参考下本文实例讲述了Yii Framework框架中事件和行为的区别及应用。分享给大家供大家参考,具体如下:个人觉得,在 Yii 里面,最难以明白的就是事件(Event)和行为(behavior)了。这不仅仅是因为它们的概念比较难明,关键是它们的应用场景比较难明,不知道什么时候应该使用事件和行为来开发。关于 Yii 的事件和行为的描述,可参考 http://www.yiiframework.com/doc/api/1.1/CComponent本文参考的文章:http://www.larryullman.com/2010/07/20/forcing-login-for-all-pages-in-yii/http://www.yiiframework.com/wiki/44/behaviors-events/http://www.cncsto.com/article/6348事件事件模型就是设计模式中的“观察者模式”:当对象的状态发生了变化,那么这个对象可以将该事件通知其它对象。为了使用事件模型,需要实现这三个步骤:1、定义事件;2、注册事件句柄;3、触发事件。为什么要做这三个步骤呢?因为对于 PHP 本身,它的执行过程不是以进程化来运行的,所以 Yii 的事件触发机制不会像 ActionScript 3+ 那样,直接将触发事件。有人说,Yii 的事件概念跟 js 中的事件概念差不多,因为 Yii 是将事件绑定到 Yii::app() 的执行过程中。由于本人对于 js 的事件没有做过深入的了解,这里不敢贸然否定,或者肯定。费话少说,先看这样的应用场景:我想在请求过来的时候,先将请求的 IP 的记录到数据库,然后才进行对应的相应的请求处理。1. 通过编辑 components/Controller.php 的构造方法来处理。如代码:12345678class Controller extends CController{public function __construct(){parent::__construct();//将请求的 IP 记录到数据库}}2. 通过使用事件来处理。我们来分析一个 framework/base/CApplication.php 的 run() 方法12345678public function run(){if($this->hasEventHandler('onBeginRequest'))$this->onBeginRequest(new CEvent($this));$this->processRequest();if($this->hasEventHandler('onEndRequest'))$this->onEndRequest(new CEvent($this));}从代码可以看出来,在处理请求之前,Yii 首先会判断一下当前有没有处理 onBeginRequest 的函数或者类的方法绑定了,如果有这样的函数或者类的方法存在,则先执行了它们,然后再处理请求。那么,怎样写 onBeginRequest,或者怎样去调用呢?方法一:修改 index.php一般来说,我们的 index.php 最后一句是:1Yii::createWebApplication($config)->run();我们在这里将它改造一下,改成:123456789$app = Yii::createWebApplication($config);Yii::app()->onBeginRequest=function($event) {//将请求的 IP 记录到数据库};Yii::app()->onBeginRequest=function($event) {//其它的你想要处理的内容,比如说,生成一个文件//file_put_contents('onBeginRequest.txt', '阿妈,我得左啦!');};$app->run();方法二:在配置文件 main.php 里面注册事件如:123456789101112131415161718192021222324/***************************************************在我们想要的内容的前后出现了这些代码只是为了说明,我们添加的内容是要放在这个配置数据的一维里面。'import'=>array('application.models.*','application.components.*','application.helpers.*',),'defaultController'=>'post',***************************************************///其它代码'import'=>array('application.models.*','application.components.*','application.helpers.*',),/************** 这才是我们想要添加的代码 **************/'onBeginRequest' => array('MyEventHandler', 'MyEventHandlerMethod'),'defaultController'=>'post',//其它代码关于 onBeginRequest 的使用,它必须是一个有效的 PHP 回调。即,一个指匿名函数,全局函数名的字符串或一个数组。如果是数组,那么该数组包含两个元素,第一个元素是一个对象,第二个元素是这个对象的方法。由此可见,方法一和方法二还是有点区别的。使用方法二的时候,只能注册一个 PHP 回调,而使用方法一,可以是不同的 PHP 回调。当然,这里说的方法二只能注册一个 PHP 回调是指,对整个请求处理过程中肯定会执行的 PHP 回调,在其它地方需要的时候,也可以加上你想实现的功能。3. 另一个例子,来说明自己是怎样定义一个事件的。打开 models/ContactForm.php,输入123456789101112131415161718/*** 自己定义发送邮件事件* @param unknown_type $event*/public function onSendMail($event){$this->raiseEvent('onSendMail',$event);}/*** 验证成功,执行* @see CModel::afterValidate()*/public function afterValidate(){if($this->hasEventHandler('onSendMail'))$this->onSendMail(new CEvent($this));}这里我们定义了一个 onSendMail 事件,并在 Validate 验证后,触发此事件。打开 controllers/SiteController.php,将修改actionContact修改为以下内容123456789101112131415161718192021public function actionContact(){$model=new ContactForm;$model->onSendMail=function($event) {$headers="From: {$event->sender->email}\r\nReply-To: {$event->sender->email}";mail(Yii::app()->params['adminEmail'],$event->sender->subject,$event->sender->body,$headers);};if(isset($_POST['ContactForm'])){$model->attributes=$_POST['ContactForm'];if($model->validate()){Yii::app()->user->setFlash('contact','Thank you for contacting us. We will respond to you as soon as possible.');$this->refresh();}}$this->render('contact',array('model'=>$model));}上面的 3 点,虽然通过绑定事件来做一些额外的处理,但同时已经暴露了一个问题,就是协同开发的时候,我不一定知道,其他开发人员写了哪些事件的 PHP 回调,在处理过程中到底会调用哪些事件的 PHP 回调。或者说,这个 PHP 回调在什么时候创建的,或者说你在为组件添加事件处理函数时,找不到合适的时候,如果添加早了,组件还没创建,如果添加晚了,事件不被执行,有可能组件已经执行完了。我们需要一个类似于配置文件的东西,将存在的事件处理组织起来,统一管理。这个时候,行为可以用上了。行为这里先重新描述一下为什么要使用行为。有两种办法可以对类添加特性:1、直接修改这个类的代码,添加一些成员函数和成员变量;2、派生,通过子类来扩展。很明显第二种方法更加易维护、易扩展。但是如果需要对一个类添加多个特性(多人在不同时期),那么需要进行多级派生,这显然加大了维护成本。在 Yii 里面,通过行为类绑定,组件将一个或多个 CBehavior 类的成员方法和成员变量添加到自己身上,并且在不需要的时候载掉某些 CBehavior 类。同时,可以通过重写 CBehavior::events 的方法,来实现对目标类的多个事件绑定。这些事件将会在当前行为绑定到目标类的时候,一起被绑定上。下面我们以代码来具体看一下这个行为特性。在 protected 创建目录 behaviors,并在protected/behaviors目录下创建ApplicationBehavior.php,输入如下代码:12345678910111213141516<?phpclass ApplicationBehavior extends CBehavior{public function events(){return array_merge(parent::events(),array('onBeginRequest'=>'beginRequest'));}public function beginRequest($event){echo "我已经将 onBeginRequest 的事件处理通过行为绑定了";}}此行为文件,是要为 CApplication 服务,仔细查看这个行为文件,我们可以看到,events 方法定义了些行为可以处理的事件,上面的类,可以处理 onBeginRequest 事件,当然如果你自己定义的组件也有一个叫做 onBeginRequest 方法,你也可以使用此行为后面的 beginRequest 就是事件的处理函数,这个处理函数必须要有行为类中定义。跟上面的事件一样,也有两种方法将此行为类附加到 CApplication。方法一:打开 index.php,输入下面代码12345678910$app = Yii::createWebApplication($config);Yii::app()->onBeginRequest=function($event) {//将请求的 IP 记录到数据库};Yii::app()->onBeginRequest=function($event) {//file_put_contents('onBeginRequest.txt', '阿妈,我又得左啦!');};/****** 这句才是我们想要的东东 *********/$app->attachBehavior('app', 'application.behaviors.ApplicationBehavior');$app->run();刷新页面,你将会在头部看到一行 “我已经将 onBeginRequest 的事件处理通过行为绑定了”方法二:如果对 Yii 的组件定义了解的话,应该知道每一个组件,都有一个behaviors方法,该方法中定义的相关行为,在组件初始化时,会自动附件,下面我们就为 CApplication 定义 behaviors,由于 CApplication 是系统级类,我们可以扩展此类,并添加behaviors方法。这里补充一下,CApplication 是会根据 config/main.php 配置进行初始化,那么我们就可以将 behaviors 定义在 main.php。打开 protected/config/main.php,加入如下代码:123'behaviors' => array('app' => 'application.behaviors.ApplicationBehavior',),刷新页面,你也会在头部看到一行 “我已经将 onBeginRequest 的事件处理通过行为绑定了”通过以上的例子,希望相关读者对 Yii 的事件和行为有一定的了解。

(0)

相关推荐

  • 系统流程

    我们来系统的了解下ThinkPHP框架开发的应用的标准执行流程: 用户URL请求 调用应用入口文件(通常是网站的index.php) 载入框架入口文件(ThinkPHP.php) 记录初始运行时间和内 ...

  • 知荐 | ADAS系统中的智能网联技术应用原理及实例分析

    ADAS系统对控制是通过利用传感器(包括雷达.摄像头.高精地图等)对前方目标进行探测和环境判断,智能网联汽车V2X主要依靠搭载车联网V2X系统,来实现车-人,车-车,车-路,车-平台的信息交换,来提高 ...

  • 【e汽车】315特刊:“机油门”事件持续发酵 雷克萨斯区别对待中美消费者

    雷克萨斯近期热度颇高. 因为机油乳化和增多的问题,导致雷克萨斯部分车型大面积出现问题. 据了解,出现问题的雷克萨斯车型包括ES.NX系列,这些出现问题的车型共同点就是相同的动力总成,问题的根源就是丰田 ...

  • 如何在Django REST框架中使用Swagger API

    WEB前端开发社区 今天 在本教程的这里,我将向您展示如何在Django REST框架中使用Swagger API.Swagger API为REST API端点提供了结构良好的文档,因此新手可以说如何 ...

  • APS在工业4.0框架中占据重要地位

    从2012到2014年,曾经帮助西门子工业撰写案例,所以对西门子工业的绝大部分产品作过研究,而在这个期间工业4.0概念的推出,通过观察西门子在工业4.0概念演变过程中,战略的变化,使我对工业4.0有较 ...

  • Django-rest framework框架

    第一章:接口规范 01 Web应用模式 02 Restful接口规范 第二章:请求渲染解析异常响应组件 01 认识Django REST framework 02 DRF环境安装与搭建 03 DRF请 ...

  • 从亚马逊的合理避税框架中,国内企业可以得到哪些启发

    许多行业企业享受不到来自国家的税收优惠政策,但税负压力很重.比如建筑行业.商贸行业等,利润高税负重但不能享受国家税收政策,必须寻找降低税负的方法. 比如亚马逊这样的超级大企业每年要交的税应该非常多,而 ...

  • 【视频讲解】在scrapy框架中如何使用selenium?

    如何在scrapy中使用selenium 上一个文章已经分享了scrapy的settings.py.spider爬虫(spider文件夹中的爬虫).items.py.pipelines.py,但没有讲 ...

  • ITIL中事件与变更的关系

    公众号回复:干货,领取价值58元/套IT管理体系文档 公众号回复:ITIL教材,领取最新ITIL4中文教材 正文 由于IT技术的发展.业务的变化.外部法规的改变,导致变更存在必然性.如何确保变更可控, ...

  • 梦境是真实的还是虚幻的?科学家:梦中事件或在平行宇宙中上演

    据资料记载,在距今约6500万年的白垩纪时期,一颗不知名的小行星突然接近地球并与地球发生了亲密接触,由此导致地球生态发生巨变,引发了第五次生物大灭绝.最终,此事件导致地球内多个物种走向灭亡,恐龙也没能 ...