【发布时间】:2015-04-07 16:21:05
【问题描述】:
所以我知道Yii::$app->user会在注销过程中触发这些事件。
const EVENT_BEFORE_LOGIN = 'beforeLogin';
const EVENT_AFTER_LOGIN = 'afterLogin';
但是在每个请求的开头添加侦听器的正确位置在哪里?
【问题讨论】:
所以我知道Yii::$app->user会在注销过程中触发这些事件。
const EVENT_BEFORE_LOGIN = 'beforeLogin';
const EVENT_AFTER_LOGIN = 'afterLogin';
但是在每个请求的开头添加侦听器的正确位置在哪里?
【问题讨论】:
最好的位置是在处理yii/web/User 身份的类中;通常,这是common/models/User。
在该类中,您可以进行以下初始化。
public function registerLogoutHook()
{
$this->on(\yii\web\User::EVENT_AFTER_LOGOUT, function ($e) {
Yii::$app->controller->goHome();
});
}
您可以选择在成功登录的[身份为`common/models/User]的Web用户对象上注册。逻辑可以如下
// [ ... omitted code ... ]
// $model is an instance of LoginForm
if ($model->load(Yii::$app->request->post()) && $model->login()) {
Yii::$app->user->identity->registerLogoutHook();
return $this->redirect(['customers/view', 'id' => Yii::$app->user->identity->id]);
}
// [ ... omitted code ... ]
另一种方式让这个工作现在(“yiisoft/yii2”:“2.0.7”)是将事件处理程序添加到您的配置文件中。这样,所有处理程序都在应用程序生命周期的早期设置。
因此,在您的 main.php 中,您将返回...
[
// ... some other things ...
'components' => [
// ... some other components ...
'user' => [
// ... some configuration for yii\web\User ...
'on beforeLogout' => function ($e) {
Yii::trace('Logout events are working!!!');
},
// ... more configurations for yii\web\User ...
],
// ... some more components ...
],
// ... some more things
]
对于处理程序,您可以使用回调、函数名称或指定要调用的对象及其方法的数组。 These methods of registering an event are enumerated here.
beforeLogout 可以更改为yii\web\User 引发的任何事件
【讨论】:
经过大量的代码挖掘,我终于找到了问题所在。您可能会认为,由于您将 User 模型作为身份传递给注销功能并为其分配事件,因此它会起作用,但实际上当前 Component 的事件正在被触发。
这意味着,如果您按照上面的建议进行操作并将事件分配给您的用户模型,它将不会被触发。相反,您需要将事件分配给 用户组件 本身。
我的解决方案(确实有效)
在您的用户模型中:
public static function beforeLogoutHook(){
// Do whatever
}
在您的代码中的某处我建议在某个全局位置执行此操作在我的情况下,我的主控制器正在被其他控制器扩展。
public function auth(){
$user = new User();
$user->setAttributes($attributes,false);
Yii::$app->user->login($user);
Yii::$app->user->on(\yii\web\User::EVENT_BEFORE_LOGOUT,function($e){
User::beforeLogout();
});
}
现在您可以在任何需要的地方简单地调用Yii::$app->user->logout();,beforeLogout 事件将被执行。
我选择在我的用户模型中声明在注销前完成工作的函数,以便更容易查找和编辑。
【讨论】: