如何在yii2中使用事件?

Posted

技术标签:

【中文标题】如何在yii2中使用事件?【英文标题】:How to use events in yii2? 【发布时间】:2015-04-18 23:35:51 【问题描述】:

我浏览了使用 Google 找到的 Yii2 events 上的文档和所有文章。谁能给我一个很好的例子来说明如何在 Yii2 中使用事件以及它看起来合乎逻辑的地方?

【问题讨论】:

这个例子可能对你有帮助 - ***.com/questions/25847013/… 【参考方案1】:

我可以通过一个简单的例子来解释事件。比方说,当用户第一次注册到网站时,您想做一些事情,例如:

    向管理员发送电子邮件。 创建通知。 你的名字。

您可以在成功保存用户对象后尝试调用一些方法。可能是这样的:

if($model->save())
   $mailObj->sendNewUserMail($model);
   $notification->setNotification($model);

到目前为止,这似乎还不错,但如果需求数量随时间增长怎么办?说用户注册后必须发生的 10 件事?在这种情况下,事件会派上用场。

活动基础

事件由以下循环组成。

    您定义一个事件。比如说,新用户注册。 你在你的模型中命名它。也许在User 模型中添加常量。喜欢const EVENT_NEW_USER='new_user';。这用于添加处理程序和触发事件。 您定义了一个在事件发生时应该做某事的方法。例如,向管理员发送电子邮件。它必须有一个$event 参数。我们将此方法称为处理程序。 您使用称为on() 的方法将该处理程序附加到model。您可以根据需要多次调用此方法 - 只需将多个处理程序附加到单个事件。 您使用trigger() 触发事件。

请注意,上面提到的所有方法都是Component 类的一部分。 Yii2 中几乎所有的类都继承自这个类。是的ActiveRecord也是。

让我们编码

为了解决上述问题,我们可能有User.php 模型。这里就不写全部代码了。

// in User.php i've declared constant that stores event name
const EVENT_NEW_USER = 'new-user';

// say, whenever new user registers, below method will send an email.
public function sendMail($event)
   echo 'mail sent to admin';
   // you code 


// one more hanlder.

public function notification($event)
  echo 'notification created';

这里要记住的一件事是,您不必在创建事件的类中创建方法。您可以从任何类中添加任何静态、非静态方法。

我需要将上述处理程序附加到事件。我做的基本方法是使用AR的init()方法。方法如下:

// this should be inside User.php class.
public function init()

  $this->on(self::EVENT_NEW_USER, [$this, 'sendMail']);
  $this->on(self::EVENT_NEW_USER, [$this, 'notification']);

  // first parameter is the name of the event and second is the handler. 
  // For handlers I use methods sendMail and notification
  // from $this class.
  parent::init(); // DON'T Forget to call the parent method.

最后是触发一个事件。现在您不需要像以前那样显式调用所有必需的方法。您可以通过以下方式替换它:

if($model->save())
  $model->trigger(User::EVENT_NEW_USER); 

所有的处理程序都会被自动调用。

【讨论】:

那里非常好和彻底的例子,对我帮助很大。我也可以将这种类型的实现用于像插件开发这样的 wordpress 吗?如果是这样,你能像上面那样说明。 @nirajanpoudel 抱歉,我不是 Wordpress 人。 这很有帮助。如果我想附加到全局 $app 我在哪里定义事件处理程序,就像你的答案一样,你在用户模型的 init() 中定义了它? afterSave 是数据库相关的事件,当你需要在记录保存后做一些事情时使用它。但在其他情况下,您需要编写自定义事件。 另一件重要的事情:将动作放在afterSave()if($model->save()) 块中将使这些动作永远在这些块中运行。但如果您使用Event,您可以控制它(根据需要打开和关闭)。我的意思是有时您不会运行这些操作,因此您不会附加任何事件。但是当您需要这些操作时,您只需执行$myModel->on('myEvent', [$myModel, 'myAction1']),它们将在“myEvent”发生时运行。根据您的系统需求,您的操作现在是可选的。【参考方案2】:

对于“全局”事件。

您可以选择创建一个专门的事件类

namespace  your\handler\Event\Namespace;
class EventUser extends Event 
   const EVENT_NEW_USER = 'new-user';

定义至少一个处理程序类:

namespace  your\handler\Event\Namespace;
class handlerClass
    // public AND static
    public static function handleNewUser(EventUser $event)
    
        // $event->user contain the "input" object
        echo 'mail sent to admin for'. $event->user->username;
    

在配置的组件部分(在这种情况下)用户组件下插入你的事件:

'components' => [
  'user' => [
    ...
    'on new-user' => ['your\handler\Event\Namespace\handlerClass', 'handleNewUser'],
  ],
  ...
]

然后在你的代码中你可以触发事件:

Yii::$app->user->trigger(EventUser::EVENT_NEW_USER, new EventUser($user));

添加

你也可以使用闭包:

允许 IDE “检测”函数的使用(用于代码导航) 放一些管理事件的(小)代码

示例:

'components' => [
  'user' => [
    ...
    'on new-user' => function($param) your\handler\Event\Namespace\handlerClass::handleNewUser($param);,
    'on increment' => function($param) \Yii::$app->count += $param->value;,
  ],   
  ... 
]

【讨论】:

任何想法为什么在句柄函数中使用$this 会引发异常"Using $this when not in object context",,例如,如果我有一个使用私有$_myVar 定义的私有属性并调用$this->_myVar 会引发上述异常 如果我没记错的话,你并不是真正的“内部”对象,所以你不能访问那个范围。你能用代码创建一个新问题吗? 我们确实在“类内部”定义了句柄函数,并通过像'on eventName'=> [ 'app\events\SubscriptionEvents', 'handleAfterTerminated', ], 这样的配置设置它,然后如果我定义一个私有类属性,我怎么不能通过$this 访问它相同的句柄函数,但如果我将它们声明为静态然后通过self调用,仍然可以访问属性或函数。 哪个php版本? 5.6 还是 7.x? 我安装了 php V7.2【参考方案3】:

默认情况下 Yii2 已经提供了一些事件声明,你可以在BaseActiveRecord 阅读更多的解释。

您可以像手动声明一样使用此变量。

public function init()

    parent::init();

    $this->on(self::EVENT_AFTER_INSERT, [$this, 'exampleMethodHere']);

【讨论】:

以上是关于如何在yii2中使用事件?的主要内容,如果未能解决你的问题,请参考以下文章

Yii2 静态方法触发事件如何实现?

Yii2 如何使用事件

如何使用 Yii2 的 PayPal 扩展在 yii2 中集成支付网关

如何在 YII2 中使用非空条件

如何在 GridView::widget、Yii2 的搜索框中使用简单的下拉列表?

Yii2.如何在 MongoDB/ActiveQuery 中使用查找?