由于 PHP 5.3 支持闭包,您可以将实例方法动态定义为持有闭包的变量:
$class->foo = function (&$self, $n) {
print "Current \$var: " . $self->var . "\n";
$self->var += $n;
print "New \$var: " .$self->var . "\n";
};
以$self(不能在对象上下文之外使用$this)作为引用(&),可以修改实例。
但是,当您尝试正常调用该函数时会出现问题:
$class->foo(2);
你得到一个致命错误。 PHP 认为foo 是$class 的一个方法,因为它的语法。此外,您必须将实例作为第一个参数传递。
幸运的是,有一个名为call_user_func 的特殊函数用于按名称调用函数:
call_user_func($class->foo, &$class, 2);
# => Current $var: 0
# => New $var: 2
记得在实例变量之前加上&。
如果你使用__call魔术方法,那就更简单了:
class MyClass {
public function __call ($method, $arguments) {
if (isset($this->$method)) {
call_user_func_array($this->$method, array_merge(array(&$this), $arguments));
}
}
}
现在您可以致电$class->foo(2)。神奇的__call 方法捕获对未知方法的调用,并调用与被调用方法同名的$class->foo 变量中的闭包。
当然,如果$class->var 是私有的,则存储在$class->foo 变量中的闭包将无法访问它。