亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Yii Framework框架中事件和行為的區別是什么

發布時間:2021-02-02 11:06:23 來源:億速云 閱讀:158 作者:小新 欄目:開發技術

這篇文章主要介紹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 的構造方法來處理。

如代碼:

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,輸入如下代碼:

<?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 Framework框架中事件和行為的區別是什么”這篇文章的所有內容,感謝各位的閱讀!希望分享的內容對大家有幫助,更多相關知識,歡迎關注億速云行業資訊頻道!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

yii
AI

旬邑县| 揭西县| 成安县| 嘉禾县| 新津县| 东港市| 兴海县| 垦利县| 环江| 湖口县| 留坝县| 锡林浩特市| 苍梧县| 泾阳县| 临潭县| 宁城县| 凉城县| 泰兴市| 福鼎市| 嘉善县| 邢台市| 甘谷县| 多伦县| 博野县| 宁夏| 宁波市| 太原市| 青神县| 信阳市| 民权县| 留坝县| 蒙阴县| 长武县| 东至县| 壤塘县| 浑源县| 修水县| 呈贡县| 平泉县| 宁波市| 上杭县|