Анонимная функция / Закрытие и использование self :: или static :: - PullRequest
9 голосов
/ 27 ноября 2011

Я работаю с анонимными функциями, где я создаю анонимную функцию вне объекта, а затем добавляю ее к объекту позже, в котором она будет использоваться с магической функцией __callStatic.Добавляемые замыкания содержат методы из родительского класса.Мне интересно, смогу ли я вызвать эти методы из замыкания?

Прямо сейчас я получаю эту ошибку:

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

    echo '<p>You have mail!</p>';
});

выдает эту ошибку:

Неустранимая ошибка: невозможно получить доступ к статическому ::, когда ни одна область классов не активна в

И

//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'

Ответы [ 3 ]

13 голосов
/ 13 июня 2012

Этого можно добиться с помощью 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();
12 голосов
/ 27 июля 2013

Просто сохраните имя класса и передайте его закрытию через 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();
3 голосов
/ 27 ноября 2011

Закрытия называются так по причине.Они «заключают» область, в которой они определены. Это не просто блоки кода, которые могут забрать область из места, в которое они вставлены.

...