如何自定义一个方法的行为却不使用继承

3.4 版本
维护中的版本

最重要文档 译注:这篇文档虽然很短,却极其重要,后面会有机会同大家深度分享。

在方法调用之前和之后做一些事 

如果你只想在方法调用之前或者之后做一些事情,你可以分别在方法开始和结束的时候派遣一个事件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
class Foo
{
    // ...
 
    public function send($foo, $bar)
    {
        // do something before the method / 在本方法(执行)之前做事
        $event = new FilterBeforeSendEvent($foo, $bar);
        $this->dispatcher->dispatch('foo.pre_send', $event);
 
        // get $foo and $bar from the event, they may have been modified
        // 从事件中得到 $foo 和 $bar,他们有可能被修改过
        $foo = $event->getFoo();
        $bar = $event->getBar();
 
        // the real method implementation is here
        // 本方法的真正实现从这里开始
        $ret = ...;
 
        // do something after the method
        // 在本方法(执行)之后做事
        $event = new FilterSendReturnValue($ret);
        $this->dispatcher->dispatch('foo.post_send', $event);
 
        return $event->getReturnValue();
    }
}

本例中,有两个事件被抛出:foo.pre_send 存在于方法执行之前,以及 foo.post_send 存在于方法执行之后。每个事件都使用了自定义的事件类来和各自事件的监听器通信。这些事件类需要你自己来创建,并且,在例程中,应该允许变量 $foo, $bar$ret (从事件中)被取出,然后交由监听器进行设置。

例如,假设 FilterSendReturnValue 有一个 setReturnValue 方法,某个监听(listener)看起来可能像下面这样:

1
2
3
4
5
6
7
public function onFooPostSend(FilterSendReturnValue $event)
{
    $ret = $event->getReturnValue();
    // modify the original '$ret' value
    // 修改原始的 $ret 值
    $event->setReturnValue($ret);
}

本文,包括例程代码在内,采用的是 Creative Commons BY-SA 3.0 创作共用授权。

登录symfonychina 发表评论或留下问题(我们会尽量回复)