Yii Frameworkフレームワークにおけるイベントと動作の違いと応用例の分析

8154 ワード

この例では,Yii Frameworkフレームワークにおけるイベントと動作の違いと応用について述べる.皆さんの参考にしてください.具体的には以下の通りです.
個人的には、Yiiの中で一番分かりにくいのがイベントと行為だと思います.これは単なる概念ではありません
比較的分かりにくく、重要なのは、それらのアプリケーションシーンが分かりにくく、いつイベントや動作を使用して開発すべきか分からないことです.
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/
≪イベント|Events|ldap≫
イベントモデルは、オブジェクトの状態が変化すると、そのオブジェクトが他のオブジェクトにイベントを通知する設計モードの「オブザーバーモード」です.イベントモデルを使用するには、この3つのステップを実現する必要があります:1、イベントを定義します;2、登録イベントハンドル;3、イベントをトリガーします.
なぜこの3つのステップをするのですか?PHP自体の場合、その実行プロセスはプロセス化で実行されないため、YiiのイベントトリガメカニズムはActionScript 3+のようにイベントを直接トリガすることはありません.Yiiのイベント概念はjsのイベント概念とあまり差がないと言われています.YiiはイベントをYii::app()にバインドする実行中であるからです.本人はjsの事件に対して深い理解をしたことがないため、ここは軽率に否定する勇気がなくて、あるいは肯定します.
話を少なくして、まずこのような応用シーンを見ます.
リクエストが来たときに、リクエストしたIPの記録をデータベースにしてから、対応するリクエスト処理を行うと思います.
1.components/Clontroller.phpの構築方法を編集することにより処理する.
コード:

class Controller extends CController
{
  public function __construct()
  {
    parent::__construct();
    //     IP       
  }
}


2.イベントを使用して処理します.
framework/base/Application.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はどのように書くか、あるいはどのように呼び出すか.
方法1: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();


方法2:プロファイル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コールバックである必要があります.
すなわち、匿名関数、グローバル関数名を指す文字列または配列.配列の場合、配列には2つの要素が含まれています.最初の要素はオブジェクトで、2番目の要素はこのオブジェクトの方法です.このように、方法1と方法2はやはり少し違います.使用方法2の場合、PHPコールバックは1つしか登録できませんが、使用方法1は、異なるPHPコールバックであってもよいです.もちろん、ここでいう方法2は1つのPHPコールバックしか登録できないということは、リクエスト処理中に必ず実行されるPHPコールバックに対して、他の場所で必要なときに、実現したい機能を加えることもできます.
3.別の例では、自分がイベントをどのように定義したかを説明します.
models/ClontactForm.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
Reply-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コールバックはいつ作成されたのか、
あるいは、コンポーネントにイベント処理関数を追加するときに、適切なものが見つからない場合は、追加が早く、コンポーネントが作成されていない場合、追加が遅くなった場合、イベントが実行されない場合は、コンポーネントが実行された可能性があります.
存在するイベント処理を組織し、管理を統一するプロファイルに似たものが必要です.この時、行為は使えます.
動作
ここではまず、なぜ動作を使用するのかを再説明します.
クラスにプロパティを追加するには、次の2つの方法があります.
1、このクラスのコードを直接修正し、メンバー関数とメンバー変数を追加します.2、派生し、サブクラスで拡張する.
2つ目の方法は、メンテナンスが容易で、拡張が容易であることが明らかです.しかし、1つのクラスに複数のプロパティを追加する必要がある場合(複数人が異なる時期に)、マルチレベル派生が必要であり、メンテナンスコストが大幅に増加することは明らかです.
Yiiでは、動作クラスバインドによって、コンポーネントは1つ以上のCBehaviorクラスのメンバーメソッドとメンバー変数を自分の体に追加し、必要でないときにいくつかのCBehaviorクラスをロードします.
同時に,CBehavior::eventsのメソッドを書き換えることで,ターゲットクラスに対する複数のイベントバインドを実現できる.これらのイベントは、現在の動作がターゲットクラスにバインドされている間に、一緒にバインドされます.
この動作特性をコードで具体的に見てみましょう.
Protectedでディレクトリbehaviorsを作成し、protected/behaviorsディレクトリの下にApplicationBehavior.phpを作成します.次のコードを入力します.

'beginRequest'
    ));
  }

  public function beginRequest($event) 
  {
    echo "     onBeginRequest             ";
  }
}


この動作ファイルは、CApplicationサービスのために、この動作ファイルをよく見てみると、eventsメソッドが動作を処理できるイベントを定義していることがわかります.
上のクラスでは、onBeginRequestイベントを処理できます.もちろん、自分で定義したコンポーネントにもonBeginRequestメソッドがある場合は、この動作を使用することもできます.
後のbeginRequestはイベントの処理関数であり、この処理関数には動作クラスで定義する必要があります.
上記のイベントと同様に、この動作クラスをCApplicationに追加する方法も2つあります.
方法1:
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のイベント処理を動作にバインドしました」という行が表示されます.
方法2:
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の事件や行為について一定の理解が求められる.
Yiiの関連内容についてもっと興味のある読者は、「Yiiフレームワーク入門及び常用技術総括」、「php優秀開発フレームワーク総括」、「smartyテンプレート入門基礎教程」、「phpオブジェクト向けプログラム設計入門教程」、「php文字列(string)用法総括」、「php+mysqlデータベース操作入門教程」及び「php一般データベース操作テクニック要約」
本稿では,Yiiフレームワークに基づくPHPプログラムの設計に役立つことを期待する.