`
litton
  • 浏览: 11605 次
  • 性别: Icon_minigender_1
  • 来自: 北京
最近访客 更多访客>>
社区版块
存档分类
最新评论

转载:Yii中直接使用event和在behavior里使用event的区别

 
阅读更多

Yii中直接使用event和在behavior里使用event的区别

本文仅讲解Event与Behavior的使用与比较,更低层的原理,请参考框架原码实现

 

1.使用现有的Event

 

现有的Event就是说Yii框架本身就为你设置好了一些事件,你只要为这些事件定义处理函数,当事件被触发,就会执行之前定义的处理函数.

我们先来了解一下CApplication类, 这个应用程序的基类,些类定义了三个事件
onBeginRequest 用户请求前处理;
processRequest: 用户请求处理;
onEndRequest: 用户请求后处理;

让我们为onBeginRequest这个事件定义一个处理函数,打开index.php,在最后一行添加如下代码:

require_once($yii);
$app = Yii::createWebApplication($config);
Yii::app()->onBeginRequest=function($event) {
	echo "Hello this onBeginRequest<br />";
};

Yii::app()->onBeginRequest=function($event) {
	echo "Hello this onBeginRequest2<br />";
};

Yii::app()->onEndRequest=function($event) {
	echo "Hello this onEndRequest<br />";
};

$app->run();

刷新页面,你将在页面的头部与低部看到了Hello this onBeginRequest,Hello this onBeginRequest2与Hello this onEndRequest
上面我们为onBeginRequest事件定义了两个处理函数,yii内部会处理函数以CList方式存储,并在事件触发时,按附加顺序执行

 

2. 自己定义事件:


打开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修改为以下内容

	/**
	 * Displays the contact page
	 */
	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));
	}

ok,我们在自定义,或直接为事件添加处理函数时,都需要想办法找到一个切入点(就是一个添加事件处理函数的位置)
比如,上面的actionContract中的$model->onSendMail=function(…和上面的index.php中添加的 Yii::app()->onBeginRequest=function(…代码也不是很优雅。 有些时候,你并不知道你要添加事件的组件,
是在什么时候创建的,或者说你在为组件添加事件处理函数时,找不到合适的时候,如果添加早了,组件还没创建,如果添加晚了,事件不被执行,有可能组件已经执行完了。比如controller,

 

3.Behavior,


上面我们已经介绍了事件的使用,和他的一些不足,下在我们来介绍一个Behavior行为,
先来看个例子
在protected创建目录behaviors,并在protected/behaviors目录下创建ApplicationBehavior.php,
打开此文件输入如下代码:

<?php
class ApplicationBehavior extends CBehavior {

	public function events()
	{
		return array_merge(parent::events(),array(
				'onBeginRequest'=>'beginRequest'
		));
	}

	public function beginRequest($event) {
		echo "Hello this Behavior beginRequest
";
	}
}

此行为文件,是要为CApplication服务,仔细查看这个行为文件,我们可以看到,
events方法定义了些行为可以处理的事件,上面的类,可以处理onBeginRequest事件,当然如果你自己定义的组件也有一个叫做onBeginRequest方法,你也可以使用此行为
后面的beginRequest就是事件的处理函数,这个处理函数必须要有行为类中定义。
ok,让我们将此行为类附加到CApplication
打开index.php,输入以下代码

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

Yii::app()->onBeginRequest=function($event) {
	echo "Hello this onBeginRequest<br />";
};

Yii::app()->onBeginRequest=function($event) {
	echo "Hello this onBeginRequest2<br />";
};

Yii::app()->onEndRequest=function($event) {
	echo "Hello this onEndRequest<br />";
};

$app->attachBehavior('app', 'application.behaviors.ApplicationBehavior');
$app->run();

刷新页面,你将会在头部看到一行Hello this Behavior beginRequest

如果说单从上面这个附加行为的方式来说,行为并没有比事件有多少方便,与优雅。
下在我们换一种方式,去掉index.php中的$app->attachBehavior(‘app’, ‘application.behaviors.ApplicationBehavior’);这行代码
如果你们yii的组件定义了解的话,你应该知道每一个组件,都有一个behaviors方法,些方法中定义的相关行为,在组件初始化时,会自动附件,
ok,下面我们就为CApplication定义behaviors,由于CApplication是系统级类,我们可以扩展此类,并添加behaviors方法,但是这样显的有点繁锁,
如果你知道,CApplication会根据config/main.php配置进行初始化,那么我们就可以将behaviors定义在main.php
打开config/main.php文件,加入以下代码

	'behaviors' => array(
		'app' => 'application.behaviors.ApplicationBehavior',
	),

刷新页面,你将在头部看到如下文字
Hello this Behavior beginRequest

Hello this onBeginRequest

Hello this onBeginRequest2

这里请注意,Hello this Behavior beginRequest 在行为中定义的方法,优先显示在了事件处理函数之前。

OK,让我们再看看如何在刚才的ContactForm模型中使用行为

创建目录protected/models/behaviors,在models下创建behaviors的目的是与应用级的behaviors区分

在protected/models/behaviors创建SendmailBehavior.php,并输入如下内容

<?php
class SendmailBehavior extends CBehavior {

	public function events()
	{
		return array_merge(parent::events(),array(
				'onSendmail'=>'sendmail'
		));
	}

	public function sendmail($event) {
			$headers="From: {$event->sender->email}\r\nReply-To: {$event->sender->email}";
			mail(Yii::app()->params['adminEmail'],$event->sender->subject,$event->sender->body,$headers);
	}
}

为ContactForm附加行为

打开ContactForm.php,添加behaviors方法,输入以下内容

	public function behaviors() {
		return array(
				'sendmail'=>'application.models.behaviors.SendmailBehavior'
		);
	}

好的,现在去修改SiteController.php文件,找到actionContact,注掉以下代码

		/*
		$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);
		};*/

ok,打开程序,重新提交Contact表单,与之前的功能一样,

3. 使用现有的行为,Yii框架已经为我们预先定义了一些行为,如CTimestampBehavior,它在zii包下,要使用它,我们先要了解它
这个行为主要目的是将模型AR类中的两个时间属性,create/update自动赋值

ok,让我们打开应用程序默认的sqlite数据库,数据库所在位置是prodcted/data/testdrive.db,创建一个表tbl_test
创建id主键,cTime int类型,还有uTime int类型允许为空,因为当插入时,yii的模型不会处理uTime字段

修改config/main.php 打开gii,方便创建模型文件models/Test.php
模型文件创建成功了,我们打开models/Test.php,附加行为,输入如下代码

	public function behaviors(){
	 	return array(
		 		'CTimestampBehavior' => array(
					'class' => 'zii.behaviors.CTimestampBehavior',
					'createAttribute' => 'cTime',	//创建属性,对应用模型的字段名
					'updateAttribute' => 'uTime',
				)
		);
	}

行为附加完成后,我们打开SiteController.php文件,创建如下代码

	public function actionCar() {
		$model = new Test;
		if ($model->save()) {
			echo 'ok';
		}
		else echo 'no';
	}

	public function actionUar() {
		$model = Test::model()->find('id=?', array(1));
		$model->save();
	}

这里我们创建了两个action,一个是模型插入,一个是模型更新
每操作一次你查看一下数据库记录,可以看到,cTime字段会自动填充,更新时uTime也会自动填充

本人水平有限,希望此篇文章对你有用。

 

 

转载地址:http://yiibook.yiiblogs.com/?p=584,感谢原作者

分享到:
评论

相关推荐

    Yii2中文手册(中文教程完整版)

    编撰中 数据库迁移(Migration) - 在团体开发中对你的数据库使用版本控制 待定中 Sphinx 待定中 Redis 待定中 MongoDB 待定中 ElasticSearch 接收用户数据 编撰中 创建表单 已定稿 输入验证 编撰中 文件上传 待定中...

    YII2框架中behavior行为的理解与使用方法示例

    在YII2中,behavior(行为)是极为重要的概念,它允许开发者在不修改原有类的基础上增加新的方法和属性,从而实现对组件功能的扩展。下面将对YII2中的behavior进行详细解析,包括其功能、原理、使用方法及注意事项。...

    深入理解Yii2.0 最新版

    事件(Event)和行为(Behavior)是Yii2.0的高级特性,涉及事件的绑定、触发和处理,以及如何在对象中定义和使用行为。 2. Yii2.0约定 Yii2.0采用特定的目录结构和约定来优化开发流程。了解Yii应用的目录结构和入口...

    yii框架2.0

    ### Yii框架2.0知识点详解 #### 一、概述 **Yii** 是一款高性能的PHP Web...通过深入了解其设计理念和技术实现,开发者不仅可以快速构建出高效稳定的Web应用,还能在开发过程中学习到先进的软件工程思想和最佳实践。

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

    个人觉得,在 Yii 里面,最难以明白的就是事件(Event)和行为(behavior)了。这不仅仅是因为它们的概念 比较难明,关键是它们的应用场景比较难明,不知道什么时候应该使用事件和行为来开发。 关于 Yii 的事件和...

    再谈Yii Framework框架中的事件event原理与应用

    事件(event)在Yii Framework中用于提供一种灵活的方式来处理特定应用程序事件的通知,允许开发者通过自定义事件处理器来响应这些事件。 在Yii Framework中,事件通常是由行为(behavior)或者核心组件触发的。...

    Yii框架组件和事件行为管理详解

    在Yii中,组件(Component)和事件行为管理(Event and Behavior Management)是其核心特性,它们使得代码更加模块化和可复用,同时提供了强大的扩展性。 **组件管理** 在Yii中,组件是一种具有独立功能的对象,...

    YII框架实现自定义第三方扩展操作示例

    在我们的示例中,`Cat`类和`Dog`类都是继承自`\yii\base\Component`类,这使得它们能够使用YII框架提供的各种功能,比如事件处理机制。我们以`Cat`类为例,它有一个`shout`方法,该方法会触发一个名为`miao`的事件,...

Global site tag (gtag.js) - Google Analytics