Yii2-Event を使用したディープラーニング

WBOY
リリース: 2016-06-13 12:28:01
オリジナル
904 人が閲覧しました

Yii2 の詳細な学習 - イベント

まず、Yii2 でのイベントの使用方法を見てみましょう。 以下の内容は Yii2 中国語ドキュメントからの抜粋です

イベントは既存のコードにカスタム コードを「挿入」できます。のコード固有の実行ポイント。カスタム コードをイベントにアタッチすると、イベントがトリガーされたときにコードが自動的に実行されます。たとえば、メーラー オブジェクトがメッセージの送信に成功すると、messageSent イベントをトリガーできます。正常に送信されたメッセージを追跡したい場合は、対応する追跡コードを messageSent イベントに添付できます。

Yii は、イベントをサポートするために [[yiibaseComponent]] という名前の基本クラスを導入します。クラスがイベントをトリガーする必要がある場合、[[yiibaseComponent]] またはそのサブクラスを継承する必要があります。

イベント ハンドラー

イベント ハンドラーは、関連付けられたイベントがトリガーされたときに実行される PHP コールバック関数です。次のコールバック関数のいずれかを使用できます:

  • 文字列形式で指定された PHP グローバル関数 ('trim' など);
  • オブジェクト名とメソッドの配列形式で指定されたオブジェクト メソッド[$object, $method] などの名前;
  • などのクラス名とメソッド名の配列の形式で指定された静的クラス メソッド [$class, $method]
  • などの匿名関数🎜>。
  • function ($event) { ... }
  • イベント ハンドラーの形式は次のとおりです。

function ($event<span>) {    // $event 是 yii\base\Event 或其子类的对象}</span>
ログイン後にコピー
パラメーターを使用すると、イベント ハンドラーはイベントに関する次の情報:

$event

[[yiibaseEvent::name|event name]]: イベント名
  • [[yiibaseEvent::sender|event sender]]: call
  • メソッド
  • trigger()[[yiibaseEvent::data|custom data]] のオブジェクト: イベント ハンドラーをアタッチするときに渡されるデータ。デフォルトは空です。詳細は以下で説明します
  • イベントのアタッチ ハンドラー

は [[yiibaseComponent::on()]] メソッドを呼び出して、ハンドラーをイベントにアタッチします。例:

$foo = new<span> Foo;// 处理器是全局函数$foo->on(Foo::EVENT_HELLO, 'function_name'<span>);// 处理器是对象方法$foo->on(Foo::EVENT_HELLO, [$object, 'methodName'<span>]);// 处理器是静态类方法$foo->on(Foo::EVENT_HELLO, ['app\components\Bar', 'methodName'<span>]);// 处理器是匿名函数$foo->on(Foo::EVENT_HELLO, function ($event<span>) {    //事件处理逻辑});</span></span></span></span></span>
ログイン後にコピー
イベント ハンドラーをアタッチする場合、[[yiibaseComponent::on()] の 3 番目のパラメーターとして追加データを指定できます。 ] 方法。イベントがトリガーされてハンドラーが呼び出されたときに、ハンドラーはデータを利用できるようになります。例:

// 当事件被触发时以下代码显示 "abc"// 因为 $event->data 包括被传递到 "on" 方法的数据$foo->on(Foo::EVENT_HELLO, function ($event<span>) {    echo $event-><span>data;}, 'abc');</span></span>
ログイン後にコピー
イベント ハンドラー シーケンス

は、1 つ以上のハンドラーをイベントにアタッチできます。イベントがトリガーされると、アタッチされたハンドラーがアタッチされた順序で呼び出されます。プロセッサが後続のプロセッサ呼び出しを停止する必要がある場合は、次のように

パラメータの [yiibaseEvent::handled]] 属性を true に設定できます:

$event

$foo->on(Foo::EVENT_HELLO, function ($event<span>) {    $event->handled = true<span>;});</span></span>
ログイン後にコピー
デフォルトでは、新しくアタッチされたイベント ハンドラーは、既存のハンドラー キューの最後にキューに入れられます。したがって、このハンドラーは、イベントが発生したときに最後に呼び出されます。プロセッサ キューの先頭に新しいプロセッサを挿入すると、そのプロセッサが最初に呼び出されます。4 番目のパラメータ を false として渡し、[[yiibaseComponent::on()]] メソッドを呼び出して実装します。 >

$append

$foo->on(Foo::EVENT_HELLO, function ($event<span>) {    // 这个处理器将被插入到处理器队列的第一位...}, $data, false);</span>
ログイン後にコピー
トリガーイベントイベントは、[[yiibaseComponent::trigger()]] メソッドを呼び出すことによってトリガーされます。このメソッドは渡す必要があります。

イベント名

に加えて、イベント オブジェクトを渡してイベント ハンドラーにパラメータを渡すこともできます。例:

<span>namespace app\components;use<span> yii\base\Component;use<span> yii\base\Event;class Foo extends<span> Component{    const EVENT_HELLO = 'hello'<span>;    public function<span> bar()    {        $this->trigger(self::<span>EVENT_HELLO);    }}</span></span></span></span></span></span></span>
ログイン後にコピー
上記のコードが を呼び出すと、 という名前のイベントがトリガーされます。

bar()helloヒント: イベント名を表すにはクラス定数を使用することをお勧めします。上記の例では、定数

を表すために使用されます。これには 2 つの利点があります。まず、タイプミスを防止し、IDE のオートコンプリートをサポートします。次に、定数の宣言を調べるだけで、クラスがどのイベントをサポートしているかを知ることができます。

EVENT_HELLOhelloイベントがトリガーされたときに、追加情報をイベント ハンドラーに渡したい場合があります。たとえば、メール プログラムは、どのメッセージが送信されたかをハンドラーが認識できるように、メッセージ情報を

イベントのハンドラーに渡す必要があります。これを行うには、[[yiibaseComponent::trigger()]] メソッドの 2 番目のパラメータとしてイベント オブジェクトを指定できます。このイベント オブジェクトは、[[yiibaseEvent]] クラスまたはそのサブクラスのインスタンスである必要があります。例:

messageSent

<span>namespace app\components;use<span> yii\base\Component;use<span> yii\base\Event;class MessageEvent extends<span> Event{    public $message<span>;}class Mailer extends<span> Component{    const EVENT_MESSAGE_SENT = 'messageSent'<span>;    public function send($message<span>)    {        // ...发送 $message 的逻辑...        $event = new<span> MessageEvent;        $event->message = $message<span>;        $this->trigger(self::EVENT_MESSAGE_SENT, $event<span>);    }}</span></span></span></span></span></span></span></span></span></span></span>
ログイン後にコピー
[[yiibaseComponent::trigger()]] メソッドが呼び出されると、名前付きイベントに関連付けられているすべてのイベント (トリガーメソッドの最初のパラメーター) イベントハンドラー。 イベント ハンドラーの削除

イベントからハンドラーを削除するには、[[yiibaseComponent::off()]] メソッドを呼び出します。例:

注意当匿名函数附加到事件后一般不要尝试移除匿名函数,除非你在某处存储了它。以上示例中,假设匿名函数存储为变量$anonymousFunction 。

移除事件的全部处理器,简单调用 [[yii\base\Component::off()]] 即可,不需要第二个参数:

$foo->off(Foo::EVENT_HELLO);
ログイン後にコピー

类级别的事件处理器

以上部分,我们叙述了在实例级别如何附加处理器到事件。有时想要一个类的所有实例而不是一个指定的实例都响应一个被触发的事件,并不是一个个附加事件处理器到每个实例,而是通过调用静态方法 [[yii\base\Event::on()]] 在类级别附加处理器。

例如,活动记录对象要在每次往数据库新增一条新记录时触发一个 [[yii\db\BaseActiveRecord::EVENT_AFTER_INSERT|EVENT_AFTER_INSERT]] 事件。要追踪每个活动记录对象的新增记录完成情况,应如下写代码:

use<span> Yii;use<span> yii\base\Event;use<span> yii\db\ActiveRecord;Event::on(ActiveRecord::className(), ActiveRecord::EVENT_AFTER_INSERT, function ($event<span>) {    Yii::trace(get_class($event->sender) . ' is inserted'<span>);});</span></span></span></span></span>
ログイン後にコピー

每当 [[yii\db\BaseActiveRecord|ActiveRecord]] 或其子类的实例触发 [[yii\db\BaseActiveRecord::EVENT_AFTER_INSERT|EVENT_AFTER_INSERT]] 事件时,这个事件处理器都会执行。在这个处理器中,可以通过 $event->sender 获取触发事件的对象。

当对象触发事件时,它首先调用实例级别的处理器,然后才会调用类级别处理器。

可调用静态方法[[yii\base\Event::trigger()]]来触发一个类级别事件。类级别事件不与特定对象相关联。因此,它只会引起类级别事件处理器的调用。如:

use<span> yii\base\Event;Event::on(Foo::className(), Foo::EVENT_HELLO, function ($event<span>) {    echo $event->sender;  // 显示 "app\models\Foo"<span>});Event::trigger(Foo::className(), Foo::EVENT_HELLO);</span></span></span>
ログイン後にコピー

注意这种情况下 $event->sender 指向触发事件的类名而不是对象实例。

Note: 因为类级别的处理器响应类和其子类的所有实例触发的事件,必须谨慎使用,尤其是底层的基类,如 [[yii\base\Object]]。

移除类级别的事件处理器只需调用[[yii\base\Event::off()]],如:

// 移除 $handlerEvent::off(Foo::className(), Foo::EVENT_HELLO, $handler<span>);// 移除 Foo::EVENT_HELLO 事件的全部处理器Event::off(Foo::className(), Foo::EVENT_HELLO);</span>
ログイン後にコピー

全局事件

所谓全局事件实际上是一个基于以上叙述的事件机制的戏法。它需要一个全局可访问的单例,如应用实例。

事件触发者不调用其自身的 trigger() 方法,而是调用单例的 trigger() 方法来触发全局事件。类似地,事件处理器被附加到单例的事件。如:

use<span> Yii;use<span> yii\base\Event;use<span> app\components\Foo;Yii::$app->on('bar', function ($event<span>) {    echo get_class($event->sender);  // 显示 "app\components\Foo"<span>});Yii::$app->trigger('bar', new Event(['sender' => new Foo]));</span></span></span></span></span>
ログイン後にコピー

全局事件的一个好处是当附加处理器到一个对象要触发的事件时,不需要产生该对象。相反,处理器附加和事件触发都通过单例(如应用实例)完成。

然而,因为全局事件的命名空间由各方共享,应合理命名全局事件,如引入一些命名空间(例:"frontend.mail.sent", "backend.mail.sent")。

 

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート