`
litton
  • 浏览: 11325 次
  • 性别: 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,感谢原作者

分享到:
评论

相关推荐

    yiiframework官方最新版,包括源程序、api、文档

    例如,你可以在你的Yii应用程序中使用PEAR或Zend Framework的代码。  17、详细的文档:每一个单一的方法或属性都非常清楚的记录着。同时提供了一个全面的教程和一些新手教程。  18、扩展库:Yii提供了一个组成用户...

    awesome-yii2:Yii2干货集

    :Yii最新动态都在这里 :Yii专用的套餐 yii:Yii学习资料和新闻 :用Yii开发的项目案例,包括开源不开源的,包括Yii1和Yii2,至今有300多个案例了。 :forecho开的摘要小专栏,欢迎有需要的朋友订阅。 Docs...

    yii2-image-style-behavior:Yii2 Images样式行为

    无论运行$ composer require artkost/yii2-image-style-behavior 或添加"artkost/yii2-image-style-behavior": "*" 到composer.json文件的require部分。配置中如下配置模型 use artkost\imagestyle\ ...

    Yii中使用PHPExcel

    Yii中使用PHPExcel,相信你看完本文档之后,疑点瞬即消失

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

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

    yii2swoole让yii2运行在swoole上

    yii2 swoole:让yii2运行在swoole上 , 运行在swoole上的yii2是运行在php-fpm上yii2的5倍以上

    yii2-request-behavior:Yii框架的请求行为

    请求Yii 2的行为Yii...用法安装扩展程序后,只需通过以下方式在Controller代码中使用该扩展程序: public function behaviors (){ return [ // code ... [ 'class' =&gt; ThrottleBehavior :: className (), 'message'

    yii2-signature:Yii2签名

    已淘汰 重要信息随着我们从单一基础架构过渡到微服务网络,并使后端与前端客户端完全分离,我们所有的Yii小部件都将停止使用。 我们鼓励您避免在CSS / ...安装扩展程序后,只需通过以下方式在您的代码中使用它:

    yii2-upload-behavior:Yii 2的Fileimage上传行为

    上传行为的Yii 2 注意:参考项目 此行为将自动上传文件,...在模型中附加行为: class Document extends ActiveRecord { /** * @inheritdoc */ public function rules () { return [ [ 'attachment' , 'file'

    Yii-1.1.10中文手册chm格式压缩包文件

    安装与配置:手册中包含了Yii框架的安装步骤和配置指南,帮助开发者正确地在他们的环境中设置Yii框架。 验证器:详细介绍了Yii框架中的验证器,如CCaptchaValidator,它用于验证用户输入的验证码是否正确。 示例与...

    深入解析PHP的Yii框架中的event事件机制

    事件 事件可以将自定义代码“注入”到现有代码中的...Yii的event机制 YII的事件机制,是其比较独特之处,合理使用好事件机制,会使各个组件之间的耦合更为松散,利于团体协作开发。 何时需要使用事件,如何给事件绑定

    vue-zhidian:YII2+VUE2开发的SCRM后台项目

    后端技术架构yiisoft/yii2yiisoft/yii2-redisyiisoft/yii2-mongodbfirebase/php-jwtaliyuncs/oss-sdk-phpphp-curl-class/php-curl-classcornernote/yii2-softdelete前端技术架构vue-clivueaxiosvue-routervuexfont-...

    material-dashboard-yii2:Yii2 Framework的Material Dashboard-Yii2 Framework的开源Bootstrap 4 Material Design Admin-Source material

    使用为Yii2构建的Bootstrap 4 Admin Dashboard加快您的Web开发速度。 笔记 我们建议将此预设安装在从头开始的项目上,否则项目的设计可能会中断。 先决条件 我们已将Docker包含在用于构建MySQL,PHP和Nginx环境的...

    Yii2.0打造京东商城平台PHP电商实战Yii2.0视频教程

    教程名称:Yii2.0 打造京东商城平台 PHP电商实战 Yii2.0视频教程 教程内容: 包含了电商的所有...不错的学习YII框架的基础课程,电商系统的结构完整、框架资源太大,传百度网盘了,链接在附件中,有需要的同学自取。

    yii2-save-relations-behavior, 验证并保存相关的Active Record 模型.zip

    yii2-save-relations-behavior, 验证并保存相关的Active Record 模型 Yii2 Active Record 保存关系行为自动验证和保存相关的Active Record 模型。 特性支持 hasMany() 和 hasOne() 关系现有的相关模型一起工作支持...

    yii2-multilingual-behavior:yii-多语言行为的Yii2端口

    Yii2多语言行为yii Yii2端口。 此行为使您可以创建多语言模型,并将其几乎用作普通模型。 每个模型的翻译都存储在数据库的单独表中(例如:PostLang或ProductLang),因此您可以轻松添加或删除语言,而无需修改...

    实例讲解yii2.0在php命令行中运行的步骤

    Yii中的资源是和Web页面相关的文件,可为CSS文件,JavaScript文件,图片或视频等,资源放在Web可访问的目录下,直接被Web服务器调用。 有时候有些功能需要做到计划任务中去,因此就需要yii能用php命令去执行。yii2.0...

    yii的小部件使用

    yii的小部件使用的总结,快速生成增删改查,感觉不同的需求进行逻辑修改!

    yii2-browser-info:Yii2扩展名。 提供有关浏览器的详细信息

    yii2-浏览器信息 Yii2扩展名。 提供有关浏览器的详细信息。 当前可用的提供商: Browscap( ) 安装 安装此扩展的首选方法是通过 。 要安装,请运行 $ ...

    yii框架中文文档、yii中文手册教程

    yii1.1中文文档 yii框架中文手册教程.pdf

Global site tag (gtag.js) - Google Analytics