Php 匿名函数/闭包并使用self::或static::

Php 匿名函数/闭包并使用self::或static::,php,static,closures,anonymous-function,Php,Static,Closures,Anonymous Function,我正在使用匿名函数,在对象外部创建匿名函数,然后将其添加到对象中,在该对象中将与_callStatic magic function一起使用。正在添加以包含父类中的方法的闭包。我想知道我是否能够从闭包中调用这些方法 现在我得到了这个错误: EmptyObject::addMethod('open', function(){ if (static::_hasAdapter(get_class(), __FUNCTION__)) return self::_callA

我正在使用匿名函数,在对象外部创建匿名函数,然后将其添加到对象中,在该对象中将与_callStatic magic function一起使用。正在添加以包含父类中的方法的闭包。我想知道我是否能够从闭包中调用这些方法

现在我得到了这个错误:

EmptyObject::addMethod('open', function(){
    if (static::_hasAdapter(get_class(), __FUNCTION__))
            return self::_callAdapter(get_class(), __FUNCTION__, $details);

    echo '<p>You have mail!</p>';
});
EmptyObject::addMethod('open',function()){
if(静态::_hasAdapter(get_class(),u函数_u))
返回self::_callAdapter(get_class(),u函数,$details);
回音“你有邮件!

”; });
抛出此错误:

EmptyObject::addMethod('open', function(){
    if (static::_hasAdapter(get_class(), __FUNCTION__))
            return self::_callAdapter(get_class(), __FUNCTION__, $details);

    echo '<p>You have mail!</p>';
});
致命错误:在中没有活动的类作用域时,无法访问static::

//添加函数
EmptyObject::addMethod('open',function()){
if(EmptyObject::_hasAdapter('EmptyObject',函数uuu))
返回EmptyObject::_调用适配器('EmptyObject',uu函数,$details);
回音“你有邮件!

”; });
抛出此错误,因为该方法受保护

致命错误:在类EmptyObject中未找到包含消息“Method”\u hasAdapter“的未捕获异常“BadMethodCallException”


这样称呼是有原因的。它们“包含”了定义它们的范围。它们不是简单的代码块,可以从粘贴到的位置获取作用域。

您可以使用(PHP>=5.4.0)实现这一点

现在,传递给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();

这是有道理的,但是如果不公开方法,您将如何实现上述目标?在javascript中,您只需将对函数的引用保存在局部变量中,并在闭包中调用它。如何在PHP中实现这一点?JavaScript和PHP中作用域的工作方式非常不同。从PHP中外部作用域在函数中如何不可见开始,到JavaScript中如何更改执行函数的作用域结束。换句话说:PHP不适合这样的元编程。也许你可以用反射扩展做点什么,但我不确定。另一种方法可能是使用eval,但这有其自身的缺点。如果是后期静态绑定,则应省略
\uuu CLASS\uuu
参数(或将其设置为
'static'
,例如默认值)。旧php。。在5.5.9中,我可以在一个匿名函数中看到“static::”
class test {
    public static function callMe() { echo 'call me '; }

    public static function runTest() {
        $class = __CLASS__;
        $call = function() use ($class) {
            $class::callMe();   
        };
        $call();
    }
}
test::runTest();