当前位置:K88软件开发文章中心网站服务器框架Yii 2.0 → 文章内容

事件(Events)

减小字体 增大字体 作者:佚名  来源:网上搜集  发布时间:2019-1-26 15:28:49

由  创建, 最后一次修改 2016-02-24 事件事件可以将自定义代码“注入”到现有代码中的特定执行点。附加自定义代码到某个事件,当这个事件被触发时,这些代码就会自动执行。例如,邮件程序对象成功发出消息时可触发?messageSent?事件。如想追踪成功发送的消息,可以附加相应追踪代码到messageSent?事件。Yii 引入了名为 yii\base\Component 的基类以支持事件。如果一个类需要触发事件就应该继承 yii\base\Component 或其子类。事件处理器(Event Handlers)事件处理器是一个PHP 回调函数,当它所附加到的事件被触发时它就会执行。可以使用以下回调函数之一:字符串形式指定的 PHP 全局函数,如?'trim'?;对象名和方法名数组形式指定的对象方法,如?[$object, $method]?;类名和方法名数组形式指定的静态类方法,如?[$class, $method]?;匿名函数,如?function ($event) { ... }?。事件处理器的格式是:function ($event) { // $event 是 yii\base\Event 或其子类的对象}通过?$event?参数,事件处理器就获得了以下有关事件的信息:yii\base\Event::name:事件名yii\base\Event::sender:调用?trigger()?方法的对象yii\base\Event::data:附加事件处理器时传入的数据,默认为空,后文详述附加事件处理器调用 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) { //事件处理逻辑});附加事件处理器时可以提供额外数据作为 yii\base\Component::on() 方法的第三个参数。数据在事件被触发和处理器被调用时能被处理器使用。如:// 当事件被触发时以下代码显示 "abc"// 因为 $event->data 包括被传递到 "on" 方法的数据$foo->on(Foo::EVENT_HELLO, function ($event) { echo $event->data;}, 'abc');事件处理器顺序可以附加一个或多个处理器到一个事件。当事件被触发,已附加的处理器将按附加次序依次调用。如果某个处理器需要停止其后的处理器调用,可以设置?$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);触发事件事件通过调用 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?的事件。提示:推荐使用类常量来表示事件名。上例中,常量?EVENT_HELLO?用来表示?hello?。这有两个好处。第一,它可以防止拼写错误并支持 IDE 的自动完成。第二,只要简单检查常量声明就能了解一个类支持哪些事件。有时想要在触发事件时同时传递一些额外信息到事件处理器。例如,邮件程序要传递消息信息到?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 方法第一个参数)的事件处理器。移除事件处理器从事件移除处理器,调用 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);类级别的事件处理器以上部分,我们叙述了在实例级别如何附加处理器到事件。有时想要一个类的所有实例而不是一个指定的实例都响应一个被触发的事件,并不是一个个附加事件处理器到每个实例,而是通过调用静态方法 yii\base\Event::on() 在类级别附加处理器。例如,活动记录对象要在每次往数据库新增一条新记录时触发一个 yii\db\BaseActiveRecord::EVENT_AFTER_INSERT 事件。要追踪每个活动记录对象的新增记录完成情况,应如下写代码:use Yii;use yii\base\Event;use yii\db\ActiveRecord;Event::on(ActiveRecord::className(), ActiveRecord::EVENT_AFTER_INSERT, function ($event) { Yii::trace(get_class($event->sender) . ' is inserted');});每当 yii\db\BaseActiveRecord 或其子类的实例触发 yii\db\BaseActiveRecord::E

[1] [2]  下一页


事件(Events)