- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章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/ 。
。
事件模型就是设计模式中的“观察者模式”:当对象的状态发生了变化,那么这个对象可以将该事件通知其它对象。 为了使用事件模型,需要实现这三个步骤:1、定义事件;2、注册事件句柄;3、触发事件.
为什么要做这三个步骤呢?因为对于 PHP 本身,它的执行过程不是以进程化来运行的, 所以 Yii 的事件触发机制不会像 ActionScript 3+ 那样,直接将触发事件。 有人说,Yii 的事件概念跟 js 中的事件概念差不多,因为 Yii 是将事件绑定到 Yii::app() 的执行过程中。 由于本人对于 js 的事件没有做过深入的了解,这里不敢贸然否定,或者肯定.
费话少说,先看这样的应用场景:
我想在请求过来的时候,先将请求的 IP 的记录到数据库,然后才进行对应的相应的请求处理.
1. 通过编辑 components/Controller.php 的构造方法来处理.
如代码:
1
2
3
4
5
6
7
8
|
class
Controller
extends
CController
{
public
function
__construct()
{
parent::__construct();
//将请求的 IP 记录到数据库
}
}
|
2. 通过使用事件来处理.
我们来分析一个 framework/base/CApplication.php 的 run() 方法 。
1
2
3
4
5
6
7
8
|
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 最后一句是:
1
|
Yii::createWebApplication(
$config
)->run();
|
我们在这里将它改造一下,改成:
1
2
3
4
5
6
7
8
9
|
$app
= Yii::createWebApplication(
$config
);
Yii::app()->onBeginRequest=
function
(
$event
) {
//将请求的 IP 记录到数据库
};
Yii::app()->onBeginRequest=
function
(
$event
) {
//其它的你想要处理的内容,比如说,生成一个文件
//file_put_contents('onBeginRequest.txt', '阿妈,我得左啦!');
};
$app
->run();
|
方法二:在配置文件 main.php 里面注册事件 。
如:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
/***************************************************
在我们想要的内容的前后出现了这些代码
只是为了说明,我们添加的内容是要放在
这个配置数据的一维里面。
'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,输入 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
/**
* 自己定义发送邮件事件
* @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修改为以下内容 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
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,输入如下代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
<?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,输入下面代码 。
1
2
3
4
5
6
7
8
9
10
|
$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,加入如下代码:
1
2
3
|
'behaviors'
=>
array
(
'app'
=>
'application.behaviors.ApplicationBehavior'
,
),
|
刷新页面,你也会在头部看到一行 “我已经将 onBeginRequest 的事件处理通过行为绑定了” 。
通过以上的例子,希望相关读者对 Yii 的事件和行为有一定的了解.
希望本文所述对大家基于Yii框架的PHP程序设计有所帮助.
原文链接:https://www.cnblogs.com/davidhhuan/archive/2012/01/19/2326123.html 。
最后此篇关于Yii Framework框架中事件和行为的区别及应用实例分析的文章就讲到这里了,如果你想了解更多关于Yii Framework框架中事件和行为的区别及应用实例分析的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
目前我的后端和前端都有 2 个 Yii 安装设置。但是在处理这个问题时,它会变得有点困惑,我想知道这是否以正确的方式完成。下面是如何设置我的文件夹结构的示例。 - backend - assets
如何禁用通知,我在 idex.php 中尝试但通知是回声,我如何禁用它。 在 php.ini 最佳答案 更新 public/index.php
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
'urlManager'=>array( 'urlFormat'=>'path', 'rules'=>array( '' => array('site/page/vie
从 Yii 到 Yii 2.0 这行代码怎么写: Yii::app()->getRequest()->getRestParams() ? 最佳答案 在我看来,相当于 Yii::app()->getRe
我想使用多个调用构建查询,但在使用此代码时出现错误 $command = Yii::app()->db->createCommand() ->select('*') ->from('{
Yii中我的模型规则函数中的以下代码 public function rules() { // NOTE: you should only define rules for those att
我正在开发一个带有主数据库和多个数据库的系统,每个客户端一次。当客户填写并提交包含所有必需详细信息的表单时,将创建客户数据库及其表。 我的问题:Yii 框架是否支持动态创建数据库和表?如果是这样,是否
我知道我可以在 Yii 中注册一个新的元标记并且我知道怎么做,但是我需要 替换我设置的默认标签,因为当我在一篇文章时,我想插入 元标记中文章的简短描述; 如何管理元标记? 最佳答案 如果您使用的是最新
我尝试仅在管理模块中加载 Yii Bootstrap 扩展,但它不起作用。我假设我需要预加载它或以某种方式启动它......谢谢! class AdminModule extends CWeb
我已经建立了新的 Yii2 项目。现在我想 reorganize folder structure在“public”和“app”两个文件夹中(实际上代表 protected 文件)。 框架中的所有代码
页面 Controller 访问规则: public function accessRules() { $isadmin = User::loadUser(
代理人: agent_id (primary key) 用户: f_id (foreign key) type 我以这种方式创建了关系 public function relations() {
大家好,感谢阅读。 我想知道如何将数字格式化为货币,或者只是在末尾附加 €。我在 yii 框架的管理页面上的 gridview 中工作。 我有这个,例如 'columns'=>array(
如何禁用 Yii 的内置身份验证? (/site/login ). 我正在使用扩展程序进行身份验证并且不想让内置登录保持打开状态 - 这可能是一个安全问题。 最佳答案 我认为您可以删除站点 Contr
使用 Yii,我想删除所有不是今天的行。 我的解决方案好吗? $query = "delete from `user_login_hash` where `day`!='".(date('Y-m-d'
gridview yii如何在一列数组值中显示两个关系值 在我的模型代码中有关系 $criteria->compare('exp.ExperienceYear',$this->Experience,
是他们对的任何常用方法吗?为我的 yii 项目添加扩展 ? 如何向我的 yii 添加扩展名 请解释 步骤 最佳答案 “ 应用程序配置 ”在安装扩展时起着重要作用。默认情况下,此配置将位于 php 文件
如何在 yii 中使用场景禁用文本字段?我有 3 类帐户 super 管理员、管理员和普通用户。所有 3 类用户都有权更新有关他们的信息,但其中一个字段 accountId 只能由 super 管理员
我在 yii 中找不到太多关于将默认范围应用于模型的文档,我想知道是否有人可以解释或指出我正确的方向。 我的问题的快速版本: 是否可以向默认范围添加关系,或者默认情况下向模型上的每个 AR 搜索添加“
我是一名优秀的程序员,十分优秀!