yii框架使用的第二天

it2025-04-06  19

今天主要熟悉了yii框架的事件处理器

yii框架的事件可以将自定义代码“注入”到现有代码中的特定执行点。 附加自定义代码到某个事件,当这个事件被触发时,这些代码就会自动执行。 例如,邮件程序对象成功发出消息时可触发 messageSent 事件。 如想追踪成功发送的消息,可以附加相应追踪代码到 messageSent 事件。

Yii 引入了名为 yii\base\Component 的基类以支持事件。 如果一个类需要触发事件就应该继承 yii\base\Component 或其子类。

首先事件处理器是一个php回调函数,当它所附加的事件被触发时它就会执行。可以使用以下回调函数之一。

字符串形式指定的 PHP 全局函数,如 ‘trim’ ;对象名和方法名数组形式指定的对象方法,如 [$object, $method] ;类名和方法名数组形式指定的静态类方法,如 [$class, $method] ;匿名函数,如 function ($event) { … } 。 事件的处理格式是: function ($event) { // $event 是 yii\base\Event 或其子类的对象 }

通过 $event 参数,事件处理器就获得了以下有关事件的信息:

event name:事件名event sender:调用 trigger() 方法的对象custom data:附加事件处理器时传入的数据,默认为空,后文详述

附加事件处理器(Attaching Event Handlers)

调用 yii\base\Component::on() 方法来附加处理器到事件上。如:

$foo = new Foo; // 处理器是全局函数 $foo->on(Foo::EVENT_HELLO, 'function_name'); // 处理器是对象方法 $foo->on(Foo::EVENT_HELLO, [$object, 'methodName']); // 处理器是静态类方法 $foo->on(Foo::EVENT_HELLO, ['app\components\Bar', 'methodName']); // 处理器是匿名函数 $foo->on(Foo::EVENT_HELLO, function ($event) { //事件处理逻辑 });

事件处理器顺序(Event Handler Order)

可以附加一个或多个处理器到一个事件。当事件被触发,已附加的处理器将按附加次序依次调用。 如果某个处理器需要停止其后的处理器调用,可以设置 event 参数的 yii\base\Event::$handled 属性为真, 如下:

$foo->on(Foo::EVENT_HELLO, function ($event) { $event->handled = true; });

默认新附加的事件处理器排在已存在处理器队列的最后。 因此,这个处理器将在事件被触发时最后一个调用。 在处理器队列最前面插入新处理器将使该处理器最先调用,可以传递第四个参数 $append 为假并调用 yii\base\Component::on() 方法实现:

$foo->on(Foo::EVENT_HELLO, function ($event) { // 这个处理器将被插入到处理器队列的第一位... }, $data, false);

触发事件(Triggering Events)

事件通过调用 yii\base\Component::trigger() 方法触发,此方法须传递事件名, 还可以传递一个事件对象,用来传递参数到事件处理器。如:

namespace app\components; use yii\base\Component; use yii\base\Event; class Foo extends Component { const EVENT_HELLO = 'hello'; public function bar() { $this->trigger(self::EVENT_HELLO); } }

以上代码当调用 bar() ,它将触发名为 hello 的事件。

有时想要在触发事件时同时传递一些额外信息到事件处理器。 例如,邮件程序要传递消息信息到 messageSent 事件的处理器以便处理器了解哪些消息被发送了。 为此,可以提供一个事件对象作为 yii\base\Component::trigger() 方法的第二个参数。 这个事件对象必须是 yii\base\Event 类或其子类的实例。 如:

namespace app\components; use yii\base\Component; use yii\base\Event; class MessageEvent extends Event { public $message; } class Mailer extends Component { const EVENT_MESSAGE_SENT = 'messageSent'; public function send($message) { // ...发送 $message 的逻辑... $event = new MessageEvent; $event->message = $message; $this->trigger(self::EVENT_MESSAGE_SENT, $event); } }

当 yii\base\Component::trigger() 方法被调用时, 它将调用所有附加到命名事件(trigger 方法第一个参数)的事件处理器。

移除事件处理器(Detaching Event Handlers)

从事件移除处理器,调用 yii\base\Component::off() 方法。如:

// 处理器是全局函数 $foo->off(Foo::EVENT_HELLO, 'function_name'); // 处理器是对象方法 $foo->off(Foo::EVENT_HELLO, [$object, 'methodName']); // 处理器是静态类方法 $foo->off(Foo::EVENT_HELLO, ['app\components\Bar', 'methodName']); // 处理器是匿名函数 $foo->off(Foo::EVENT_HELLO, $anonymousFunction);

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

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

$foo->off(Foo::EVENT_HELLO);
最新回复(0)