Intereting Posts
как показать / скрыть divs, когда divs создаются динамически Laravel 5.3 Войти переадресации на разные страницы для нескольких пользователей Я могу отправить данные формы с помощью метода GET, но не POST, почему? Мне нужны необычные заказы mysql Php массив с массивом я не могу создать Получение временной отметки с последней субботы (каждую неделю)? ftp_get (): Не удается открыть файл1: нет такого файла или каталога в Что такое нормализованный UTF-8? Формат PHP date () при вставке в datetime в MySQL Подключение к серверу PHP с помощью Swift Перенос файлов с локального компьютера на удаленный сервер с помощью php-скрипта, находящегося на удаленном сервере Являются ли конструкторы абстрактного класса неявным образом вызваны при создании экземпляра производного класса? Как получить последний запрос выполнения в CakePHP 3.2? Как реализовать текстовую коррекцию алгоритма для замены слов в тексте? Устранение неполадок ClassNotFoundException при использовании моста PHP / Java

Как вызвать замыкание, которое является переменной класса?

class MyClass { var $lambda; function __construct() { $this->lambda = function() {echo 'hello world';}; // no errors here, so I assume that this is legal } } $myInstance = new MyClass(); $myInstance->lambda(); //Fatal error: Call to undefined method MyClass::lambda() 

Итак, каков правильный синтаксис для достижения переменных класса?

Solutions Collecting From Web of "Как вызвать замыкание, которое является переменной класса?"

В PHP методы и свойства находятся в отдельном пространстве имен (у вас может быть метод и свойство с тем же именем), и независимо от того, используете ли вы свойство или метод, зависит от синтаксиса, который вы используете для этого.

$expr->something() – вызов метода, поэтому PHP будет искать something в списке методов класса.

$expr->something есть свойство fetch, поэтому PHP будет искать something в списке свойств класса.

$myInstance->lambda(); анализируется как вызов метода, поэтому PHP ищет метод с именем lambda в вашем классе, но такого метода нет (следовательно, вызов для неопределенной ошибки метода ).

Поэтому вам нужно использовать синтаксис свойства fetch для извлечения лямбда, а затем вызвать его.

  • Начиная с PHP 7.0, вы можете сделать это с помощью ($obj->lambda)() :

     ($obj->lambda)(); 

    В скобках убедитесь, что PHP анализирует ($obj->lambda) как свойство свойства lambda . Затем () вызывает результат получения свойства.

  • или вы можете сделать это с помощью ->lambda->__invoke() :

     $myInstance = new MyClass(); $myInstance->lambda->__invoke(); 

    __invoke является одним из магических методов PHP . Когда объект реализует этот метод, он становится invokable: его можно вызвать с помощью синтаксиса $var() . Анонимными функциями являются экземпляры Closure , которые реализуют __invoke .

  • Или назначьте его локальной переменной:

     $lambda = $myInstance->lambda; $lambda(); 
  • Или вызовите его с помощью call_user_func:

     call_user_func($myInstance->lambda); 

    call_user_func может вызывать любые callable , включая анонимные функции.

  • В качестве альтернативы, если это общий шаблон в коде, вы можете настроить метод __call для переадресации вызовов на ваш лямбда:

     class MyClass { private $lambda; public function __construct() { $this->lambda = function() { echo "Hello world!\n"; }; } public function __call($name, $args) { return call_user_func_array($this->$name, $args); } } 

    Теперь это работает:

     $myInstance = new MyClass(); $myInstance->lambda(); 

    Начиная с PHP 5.4 вы можете даже сделать это в признаке:

     trait LambdasAsMethods { public function __call($name, $args) { return call_user_func_array($this->$name, $args); } } class MyClass { use LambdasAsMethods; private $lambda; public function __construct() { $this->lambda = function() { echo "Hello World!\n"; }; } } $myInstance = new MyClass(); $myInstance->lambda(); 

Вы также можете вызвать свою лямбда-функцию без каких-либо изменений в своем классе, используя ReflectionFunction.

 $myInstance = new MyClass(); $lambda = new ReflectionFunction($myInstance->lambda); $lambda->invoke(); 

или если вам нужно передать аргументы, то

 $args = array('arg'=>'value'); $lambda->invokeArgs($args);