En PHP, los métodos y las propiedades están en un espacio de nombre separado (puede tener un método y una propiedad con el mismo nombre) y si está accediendo a una propiedad o un método depende de la sintaxis que utiliza para hacerlo .
$expr->something()
es una llamada a método, por lo que PHP buscará something
en la lista de métodos de la clase.
$expr->something
es una búsqueda de propiedad, por lo que PHP buscará something
en la lista de propiedades de la clase.
$myInstance->lambda();
se analiza como una llamada de método, por lo que PHP busca un método llamado lambda
en su clase, pero no hay tal método (de ahí el La llamada al método definido error).
Así que tiene que utilizar la búsqueda de la propiedad sintaxis para recuperar el lambda, y luego llamarlo.
A partir de PHP 7.0, puede hacer esto con ($obj->lambda)()
:
($obj->lambda)();
Los paréntesis se aseguran de que PHP analiza como ($obj->lambda)
buscar a la propiedad llamado lambda. Luego, ()
llama al resultado de ir a buscar la propiedad.
o se puede hacer esto con ->lambda->__invoke()
:
$myInstance = new MyClass();
$myInstance->lambda->__invoke();
__invoke
es uno de PHP's magic methods. Cuando un objeto implementa este método, se vuelve invocable: se puede invocar utilizando la sintaxis $var()
. Las funciones anónimas son instancias de Closure
, que implementa __invoke
.
O asignarlo a una variable local:
$lambda = $myInstance->lambda;
$lambda();
O llamarlo usando call_user_func:
call_user_func($myInstance->lambda);
call_user_func
puede llamar a cualquier callable
, incluyendo funciones anónimas.
Alternativamente, si se trata de un patrón común en su código, se puede configurar un método __call
permite desviar las llamadas a su lambda:
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);
}
}
Ahora bien, esto funciona:
$myInstance = new MyClass();
$myInstance->lambda();
A partir de PHP 5.4 que incluso puede hacer que en un rasgo:
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();
explicación Bastante perfecto =) – Rudie
Niza, aunque sería agradable ver '__invoke /()' 'vs. call_user_func' notas. –
¡Muy buena explicación! Muy rico en ejemplos. – Ricardo