1

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

关于这个这个文档,你必须将一个事件附加到一个类中,并且你必须在代码中的某个地方引发这个事件。

但据我了解,钩子系统的工作原理是这样的:

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

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

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

编辑:
我要求类似于beforeSave()and的功能afterSave()。因为那些事件你不需要提出。

4

1 回答 1

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 的简单类。我们可以使用它将有关事件的信息传递给事件处理程序:

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);
}

您也可以在行为中声明事件,但这是另一回事。

于 2014-05-13T12:25:05.570 回答