Yii事件处理如何工作?

时间:2014-05-13 10:29:27

标签: php yii hook yii-events

我不太确定钩子系统和Yii的事件处理系统是否相同。

关于thisthis文档,您必须将事件附加到类以及代码中的某个位置,您必须引发此事件。

但据我所知,钩子系统的工作原理如下:

class foo {    
  public function bar()
  {
    //do something
  }    
}

现在你定义一个名为beforeFooBar($obj)afterFooBar($obj)的函数(取决于框架),并在执行函数bar()之前或之后调用此函数。

Yii中有类似的东西吗?或者我对钩子系统的理解是完全错误的?

修改
我要求的功能类似于beforeSave()afterSave()。因为那些事件你不需要提高。

1 个答案:

答案 0 :(得分:1)

对不起,我不知道"自动挂钩"但是这里是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的简单类。我们可以使用它将有关事件的信息传递给eventhandler:

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()。否则,当您尝试将事件处理程序附加到对象时,您将获得一些异常。 但你可以把这些&#34;放在&#34;方法除了抽象类或其他东西,所以他们不会打扰你。

另请注意,您无需创建自己的事件类,只需直接使用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);
}

您也可以在行为中声明事件,但这是一个不同的故事。