本文实例讲述了Yii Framework框架中事件和行为的区别及应用。分享给大家供大家参考,具体如下:

个人觉得,在 Yii 里面,最难以明白的就是事件(Event)和行为(behavior)了。这不仅仅是因为它们的概念

比较难明,关键是它们的应用场景比较难明,不知道什么时候应该使用事件和行为来开发。

本文参考的文章:

事件

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

为了使用事件模型,需要实现这三个步骤:1、定义事件;2、注册事件句柄;3、触发事件。

为什么要做这三个步骤呢?因为对于 PHP 本身,它的执行过程不是以进程化来运行的,

所以 Yii 的事件触发机制不会像 ActionScript 3+ 那样,直接将触发事件。

有人说,Yii 的事件概念跟 js 中的事件概念差不多,因为 Yii 是将事件绑定到 Yii::app() 的执行过程中。

由于本人对于 js 的事件没有做过深入的了解,这里不敢贸然否定,或者肯定。

费话少说,先看这样的应用场景:

我想在请求过来的时候,先将请求的 IP 的记录到数据库,然后才进行对应的相应的请求处理。

1. 通过编辑 components/Controller.php 的构造方法来处理。

如代码:

class Controller extends CController

{

public function __construct()

{

parent::__construct();

//将请求的 IP 记录到数据库

}

}

2. 通过使用事件来处理。

我们来分析一个 framework/base/CApplication.php 的 run() 方法

public 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 最后一句是:

Yii::createWebApplication($config)->run();

我们在这里将它改造一下,改成:

$app = Yii::createWebApplication($config);

Yii::app()->onBeginRequest=function($event) {

//将请求的 IP 记录到数据库

};

Yii::app()->onBeginRequest=function($event) {

//其它的你想要处理的内容,比如说,生成一个文件

//file_put_contents('onBeginRequest.txt', '阿妈,我得左啦!');

};

$app->run();

方法二:在配置文件 main.php 里面注册事件

如:

/***************************************************

在我们想要的内容的前后出现了这些代码

只是为了说明,我们添加的内容是要放在

这个配置数据的一维里面。

'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,输入

/**

* 自己定义发送邮件事件

* @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修改为以下内容

public 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,输入如下代码:

class 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,输入下面代码

$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,加入如下代码:

'behaviors' => array(

'app' => 'application.behaviors.ApplicationBehavior',

),

刷新页面,你也会在头部看到一行 “我已经将 onBeginRequest 的事件处理通过行为绑定了”

通过以上的例子,希望相关读者对 Yii 的事件和行为有一定的了解。

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

php行为和事件是什么,Yii Framework框架中事件和行为的区别及应用实例分析相关推荐

  1. php excel 组件,Yii Framework框架使用PHPExcel组件的方法示例

    本文实例讲述了Yii Framework框架使用PHPExcel组件的方法.分享给大家供大家参考,具体如下: PHPExcel下载地址http://www.yiiframework.com/exten ...

  2. .net framework 4中SpinLock和lock的区别

    SpinLock,自旋锁.尝试获取该锁的线程持续不断的check是否可以获得.此时线程仍然是激活状态,只是在空转,浪费cpu而已.但是spinlock避免了线程调度和上下文切换,如果锁的时间极短的话, ...

  3. net.sz.framework 框架 ORM 消消乐超过亿条数据排行榜分析 天王盖地虎

    序言 天王盖地虎, 老婆马上生孩子了,在家待产,老婆喜欢玩消消乐类似的休闲游戏,闲置状态,无聊的分析一下消消乐游戏的一些技术问题: 由于我主要是服务器研发,客户端属于半吊子,所以就分析一下消消乐排行榜 ...

  4. [Yii Framework] Yii如何实现前后台的session分离

    Yii Framework实现前后台frontend,backend分离的方法有几种,总结如下: 1. 分开入口文件 目录结构 index.php admin.php assets/ ...其它目录 ...

  5. php事件和行为,Yii框架组件和事件行为管理详解

    Yii框架组件和事件行为管理详解 来源:中文源码网    浏览: 次    日期:2018年9月2日 [下载文档:  Yii框架组件和事件行为管理详解.txt ] (友情提示:右键点上行txt文档名- ...

  6. [Yii Framework] spl_autoload_register 导致加载顺序冲突

    php版本 davidhhuan@davidhhuan-ThinkPad-T410:~$ php -version PHP 5.3.10-1ubuntu3.4 with Suhosin-Patch ( ...

  7. [转]Yii Framework: 从 model 中生成 select option

    转载自: http://www.cnblogs.com/analyzer/articles/1673016.html 在 Yii framework 的论坛有人问,如何用 yii 的方式来生成一个下拉 ...

  8. YII framework CComponent基础类解读(转)

    CComponent CComponent类为YII框架的基于组件和事件驱动编程提供了基础,YII框架中的大部分类都将CComponent类作为基类.CComponent类为它的子类提供3个特性: 1 ...

  9. php detailview,PHP开发框架Yii Framework教程(31) Zii组件-DetailView示例

    CDetailView为某个Model显示详细内容.这个要显示的Model可以为CModel或是关联数组. CDetailView通过配置 attributes来决定Model的那些属性需要显示已经以 ...

最新文章

  1. 1351.统计有序矩阵中的负数
  2. 多线程经典问题之多窗口卖票
  3. 【Python】Python库之Web网站开发
  4. linux故障转移集群,部署AlwaysOn第一步:搭建Windows服务器故障转移集群
  5. IDEA 查看本地历史版本
  6. 精通那么多技术,你为何还是受不到重用?
  7. QTP简单框架(1)之框架简介
  8. 几个北邮和交大学霸的公众号,值得学习
  9. flask web开发是前端还是后端_后端开发该不该学前端开发?
  10. 8款微信公众号编辑器,哪个最好用?
  11. PPT文档转换成Word文档
  12. 《会计学》的简单了解
  13. 《实用回归分析》 何晓群 第五章
  14. 推荐机制 协同过滤和基于内容推荐的区别
  15. Altium的基本使用方法
  16. Python:实现GrabCut算法(附完整源码)
  17. Cascade Classification
  18. 联通服务器维护破解限速,网速1mbps(联通限速1mbps解除方法)
  19. photoshop注册机,这个必须留下来
  20. 2022美赛数学建模B题思路分享

热门文章

  1. 推荐一个CSLab------英真时代(非广告,真心的)
  2. iis mysql 无法启动_Windows下使用IIS搭建PHP环境无法开启Mysql支持的解决方法
  3. dubbo和zookeper使用_Dubbox与Zookeeper简介及入门小案例
  4. mysql行级锁unique_MySQL行级锁,表级锁,页级锁详解
  5. shell while 结束循环_Shell脚本编程2 for循环/while循环
  6. Android从启动到程序运行整个过程的整理
  7. java list 赋值jsp,在Struts中使用JavaBean和List(多行数据)类型属性-JSP教程,Java技巧及代码...
  8. python中qt有哪些控件_使用PyQt5调用Qt程序,基础PythonQt控件的使用方法
  9. c语言file_C语言程序的编译和调试
  10. cad二次开发加载cad自动调用_python实例_cad半自动绘图