Ответ 1
В PHP методы и свойства находятся в отдельном пространстве имен (вы можете иметь метод и свойство с тем же именем), и независимо от того, используете ли вы свойство или метод, зависит от синтаксиса, который вы используете для этого.
$expr->something()
- вызов метода, поэтому PHP будет искать something
в списке методов класса.
$expr->something
- это свойство fetch, поэтому PHP будет искать something
в списке свойств класса.
$myInstance->lambda();
анализируется как вызов метода, поэтому PHP ищет метод с именем lambda
в вашем классе, но такого метода нет (следовательно, ошибка метода вызова undefined).
Поэтому вам нужно использовать синтаксис свойства 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();