yii2.0事件机制必须继承yii\base\component,使用on()/off()/trigger()实例方法绑定触发,behavior是常用搭档,yii1.1写法完全不兼容。

Yii2.0 的事件机制不是“怎么用”的问题,而是必须按新规则写,Yii1.1 完全不兼容——类结构、触发方式、绑定语法、甚至基础类都变了,硬套旧写法会直接报错。
事件必须基于 yii\base\Component
Yii2.0 中只有继承 yii\base\Component 的类才支持事件(比如 Controller、Application、ActiveRecord),而 yii\base\Object(轻量基类)不支持事件。
如果你自定义类想用事件,不能只继承 Object,得改成:
use yii\base\Component;
class MyService extends Component { ... }
否则调 on()、trigger() 都会提示方法不存在。
绑定和触发写法全换掉了
Yii1.1 是全局静态调用(如 CComponent::attachEventHandler()),Yii2.0 改为实例方法 + 统一 on() / off() / trigger():
-
绑定事件(比如监听用户登录后动作):
Yii::$app->user->on(\yii\web\User::EVENT_AFTER_LOGIN, function ($event) { \Yii::info('用户登录成功:' . $event->sender->id); }); -
触发事件(在你的类里):
$this->trigger(self::EVENT_AFTER_PROCESS);
-
移除监听(避免内存泄漏或重复执行):
Yii::$app->user->off(\yii\web\User::EVENT_AFTER_LOGIN, $handler);
注意:$event->sender 指触发者对象,$event->name 是事件名,$event->data 可传额外参数。
行为(Behavior)是事件的常用搭档
单独写事件容易散落在各处,推荐把通用逻辑(如日志、权限、审计)封装成 Behavior,再挂到控制器或模型上:
// 在行为类中
public function events()
{
return [
Controller::EVENT_BEFORE_ACTION => 'beforeActionHandler',
ActiveRecord::EVENT_AFTER_INSERT => 'logInsert',
];
}
public function beforeActionHandler($event)
{
if (!$this->checkAccess($event->action->id)) {
$event->isValid = false; // 关键:不是 return false
throw new ForbiddenHttpException('无权限');
}
}
然后在控制器里 public function behaviors() { return [MyBehavior::class]; } 即可复用。
Yii1.1 代码无法直接运行
以下常见写法在 Yii2.0 中全部失效:
- ❌
CComponent::attachEventHandler('onSomething', ...)→ 不存在该方法 - ❌
$obj->onSomething = function(){}→ 不再支持魔术属性赋值 - ❌
raiseEvent('onSomething')→ 方法已移除 - ❌ 使用
CEvent类 → Yii2 用yii\base\Event,结构不同
即使你手动 use 了旧类名,Composer 也不会加载 Yii1.1 的文件——框架底层自动加载器只认 yii\* 命名空间。
不复杂但容易忽略











