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

时间:2011-11-27 17:18:31

标签: php static closures anonymous-function

我正在使用匿名函数,我在对象之外创建匿名函数,然后将其添加到稍后将与__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>';
});

抛出此错误,因为该方法受到保护

  

致命错误:在类EmptyObject'中找不到带有消息'Method'ahasAdapter'的未捕获异常'BadMethodCallException'

3 个答案:

答案 0 :(得分:13)

您可以使用Closure::bind()(PHP&gt; = 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();

答案 1 :(得分:12)

只需存储类名,然后通过use将其传递给闭包。您可以调用任何公共静态方法或以这种方式获取公共静态属性或常量。如果将闭包传递给不同的上下文,只要在创建$class时将class test { public static function callMe() { echo 'call me '; } public static function runTest() { $class = __CLASS__; $call = function() use ($class) { $class::callMe(); }; $call(); } } test::runTest(); 的正确值传递给它,它仍然会起作用。适用于php 5.3:

{{1}}

答案 2 :(得分:3)

出于某种原因,

Closures被称为这样。它们“包含”了它们所定义的范围。它们不仅仅是代码块,它们可以从它们被粘贴的位置获取范围。