很抱歉,我不知道“自动挂钩”,但这里是 Yii 中事件处理的工作原理:
这是一个没有什么特别的测试类,只有一个test()
输出一些文本的函数。它可以是任何东西,例如模型、组件或其他任何东西:
class TestClass extends CComponent
{
public function test()
{
echo 'Running test()<br />';
echo 'Now firing event<br />';
$event = new TestEvent($this, 1, 'someTestParam'); // see TestEvent class constructor
$this->onTest($event);
}
public function onTest($event)
{
$this->raiseEvent('onTest', $event);
}
}
在方法test()
中,我们创建事件对象并将其传递给onTest()
引发事件的方法。事件对象是一个扩展 CEvent 的简单类。我们可以使用它将有关事件的信息传递给事件处理程序:
class TestEvent extends CEvent
{
public $var1;
public $var2;
public function __construct(TestClass $sender, $var1, $var2)
{
parent::__construct($sender);
$this->var1 = $var1;
$this->var2 = $var2;
}
}
控制器动作如下所示:
public function actionEventTesting()
{
// create a new class
$class = new TestClass();
// attach an event handler
$class->onTest[] = function($event) {
echo "Attached Event1 raised<br />";
var_dump($event);
};
// attach a 2nd event handler (note that this is another method of attaching as before)
$class->attachEventHandler('onTest', function($event) {
echo "Attached Event2 raised<br />";
var_dump($event);
});
// call our test method
$class->test();
}
请注意,您可以像这样引发事件:
class TestClass extends CComponent
{
public function test()
{
echo 'Running test()<br />';
echo 'Now firing event<br />';
$event = new TestEvent($this, 1, 'someTestParam');
// this one is different as before
$this->raiseEvent('onTest', $event);
}
public function onTest($event)
{
// empty
}
}
我不知道为什么,但是onTest()
即使它是空的,您也需要该方法。否则,当您尝试将事件处理程序附加到对象时,您会遇到一些异常。但是您可以将这些“on”方法放在一个抽象类或其他东西中,这样它们就不会打扰您。
另请注意,您不需要创建自己的事件类,您可以直接使用CEvent
并传递参数给它:
public function test()
{
echo 'Running test()<br />';
echo 'Now firing event<br />';
$event = new CEvent($this, array('var1' => 1, 'var2' => 'someTestParam'));
$this->onTest($event);
}
您也可以在行为中声明事件,但这是另一回事。