我正在使用匿名函数,我在对象外部创建匿名函数,然后将其添加到稍后将与__callStatic魔术函数一起使用的对象中。要添加的闭包包含来自父类的方法。我想知道我是否能够从闭包调用这些方法?
现在我得到这个错误:
EmptyObject::addMethod('open', function(){
if (static::_hasAdapter(get_class(), __FUNCTION__))
return self::_callAdapter(get_class(), __FUNCTION__, $details);
echo '<p>You have mail!</p>';
});
抛出这个错误:
致命错误:
中没有活动的类作用域时,无法访问static::
和
//Add the functions
EmptyObject::addMethod('open', function(){
if (EmptyObject::_hasAdapter('EmptyObject', __FUNCTION__))
return EmptyObject::_callAdapter('EmptyObject', __FUNCTION__, $details);
echo '<p>You have mail!</p>';
});
抛出这个错误,因为方法是受保护的
致命错误:未捕获的异常'BadMethodCallException'与消息'方法'_hasAdapter'在类EmptyObject'中未找到
可以使用Closure::bind() (PHP>= 5.4.0)
abstract class EmptyObject
{
protected static $methods = array();
final public static function __callStatic($name, $arguments)
{
return call_user_func(self::$methods[$name], $arguments);
}
final public static function addMethod($name, $fn)
{
self::$methods[$name] = Closure::bind($fn, NULL, __CLASS__);
}
final protected static function protectedMethod()
{
echo __METHOD__ . " was called" . PHP_EOL;
}
}
现在任何传递给EmptyObject::addMethod()的匿名函数都将在EmptyObject类的作用域中运行
EmptyObject::addMethod("test", function()
{
self::protectedMethod();
});
// will output:
// EmptyObject::protectedMethod was called
EmptyObject::test();
只需存储类名并通过use
传递给闭包。您可以通过这种方式调用任何公共静态方法或获取公共静态属性或常量。如果闭包被传递到不同的上下文中,只要在创建时传递给它正确的$class
值,它仍然可以工作。适用于php 5.3:
class test {
public static function callMe() { echo 'call me '; }
public static function runTest() {
$class = __CLASS__;
$call = function() use ($class) {
$class::callMe();
};
$call();
}
}
test::runTest();
这样调用闭包是有原因的。它们"封闭"了定义它们的作用域。它们不是简单的代码块,可以从它们粘贴到的地方获取作用域。