我想在请求过来的时候,先将请求的 IP 的记录到数据库,然后才进行对应的相应的请求处理。
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 的函数或者类的方法绑定了,
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 验证后,触发此事件。
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 点,虽然通过绑定事件来做一些额外的处理,但同时已经暴露了一个问题,就是协同开发的时候,我不一定知道,
行为
1
2
3
4
5
6
7
8
9
10
11
12
|
public function
events() { return array_merge (parent::events(), array ( 'onBeginRequest' => 'beginRequest' )); } public function
beginRequest( $event ) { echo "我已经将
onBeginRequest 的事件处理通过行为绑定了" ; } } |
此行为文件,是要为 CApplication 服务,仔细查看这个行为文件,我们可以看到,events 方法定义了些行为可以处理的事件,
跟上面的事件一样,也有两种方法将此行为类附加到 CApplication。
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(); |
方法二:
1
2
3
|
'behaviors' =>
array ( 'app' =>
'application.behaviors.ApplicationBehavior' , ), |
通过以上的例子,希望相关读者对 Yii 的事件和行为有一定的了解。