推荐使用继承 yii\base\event 的自定义事件类传递参数,需将字段声明为 public 属性;匿名函数可借助 $event->data,但直接传数组或简单值无效。

在 Yii2 中,触发自定义事件并传递参数后,在事件监听(处理)函数中读取参数,核心是通过继承 yii\base\Event 的自定义事件类,或使用匿名函数/闭包配合 $event 对象的 $data 属性。直接用数组或简单值传参是无效的——Yii2 事件机制要求参数必须封装在 $event 实例中。
使用自定义事件类(推荐,类型安全、可扩展)
定义一个继承 yii\base\Event 的子类,把需要传递的字段声明为 public 属性:
// components/OrderPaidEvent.php
<?php namespace app\components;
use yii\base\Event;
class OrderPaidEvent extends Event
{
public $orderId;
public $amount;
public $userId;
}
触发时创建该事件实例并赋值:
// 在业务逻辑中触发
use app\components\OrderPaidEvent;
$event = new OrderPaidEvent();
$event->orderId = 123;
$event->amount = 99.9;
$event->userId = 456;
$this->trigger('order.paid', $event);
监听函数中直接访问属性:
// 绑定监听(例如在控制器 init() 或行为 attach() 中)
$this->on('order.paid', function ($event) {
echo "订单 {$event->orderId} 支付成功,金额 {$event->amount}";
});
使用 $event->data 传递简单数据(轻量场景)
若只需传 1–2 个简单值(如字符串、数字、数组),可复用 yii\base\Event 自带的 $data 属性:
- 触发时:将参数作为
$data传入(支持任意类型,常用数组) - 监听时:从
$event->data取值,需自行判断结构
// 触发
$this->trigger('user.login', new \yii\base\Event([
'data' => ['userId' => 789, 'ip' => '192.168.1.1']
]));
// 监听
$this->on('user.login', function ($event) {
$data = $event->data;
if (is_array($data)) {
echo "用户 {$data['userId']} 登录,IP:{$data['ip']}";
}
});
注意:不能直接 trigger('xxx', ['a'=>1, 'b'=>2])
以下写法不会生效,因为 Yii2 的 trigger() 第二个参数必须是 Event 实例:
// ❌ 错误:数组会被忽略,$event 在监听器里是空的 yii\base\Event 实例
$this->trigger('test', ['msg' => 'hello']);
// ✅ 正确:必须包装成 Event 对象
$this->trigger('test', new \yii\base\Event(['data' => ['msg' => 'hello']]));
监听函数签名与 $event 对象来源
无论哪种方式,监听函数接收到的 $event 都是 yii\base\Event 或其子类实例。它默认包含:
-
$event->name:事件名(如 'order.paid') -
$event->sender:触发事件的对象(即$this) -
$event->handled:是否已被处理(可用于中断后续监听) -
$event->data:手动传入的附加数据(仅当构造时指定) - 若为自定义类,还有你声明的全部 public 属性











