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