2

编码:

final class SimpleEventManager {
    private $listeners = array();

    public function listen($event, $callable) {
        $this->listeners[$event][] = $callable;
    }

    public function fire($event, array $arguments = array()) {
        foreach ($this->listeners[$event] as $listener) {
            call_user_func_array($listener, $arguments);
        }
    }
}

$manager = new SimpleEventManager;
$manager->listen('sql', function($sql) {
    $sql .= " order by username desc";
});
$sql = "select * from users";
$manager->fire('sql', array($sql));
var_dump($sql); // is: select * from users
                // want: select * from users order by username desc

所以基本上我希望我的事件监听器能够修改传入的参数。我试过做类似的事情,array &$arguments = array()但后来我得到了Cannot pass parameter 2 by reference错误。

有谁知道我该如何解决这个问题?

4

1 回答 1

2

您不能通过引用传递它,因为只有变量可以通过引用传递。文字array($sql)显然不是变量。

也就是说,这不是问题。

其实问题很多,主要是因为$sql被“复制”了这么多次:

  1. 创建时array($sql)
  2. 调用时fire()(由于没有通过引用传递)
  3. 调用匿名函数时(同样,不是通过引用传递)

首先,您需要将数组定义为变量,例如$arr = array(&$sql);

&$arguments然后保持您当前通过引用传递的“修复” 。

最后,将您的匿名函数调整function(&$sql)为也可以通过引用工作。

总而言之,如果您的代码不那么复杂,这会变得容易得多;)

于 2013-09-06T16:19:50.550 回答