2011-08-18 20 views
20

usando la siguiente función:la determinación de si una variable es un cierre válida en PHP

function is_closure($t) { return (!is_string($t) && is_callable($t)); }

Puede este retorno cierto para cualquier otra cosa, que una función de cierre en el anonimato? De ser así, ¿cuál sería la forma correcta de determinar si una variable es un cierre?

Muchas gracias

+2

Los objetos también son exigibles si implementan [ '__invoke'] (http://www.php.net/manual/en/language.oop5.magic.php#language.oop5.magic.invoke). – mario

Respuesta

40

La forma más determinista para comprobar si una devolución de llamada es un cierre real es:

function is_closure($t) { 
    return is_object($t) && ($t instanceof Closure); 
} 

Todas las funciones anónimas se representan como objetos del tipo Closure en PHP. (Que, volviendo al comentario anterior, sucede que implementa el método __invoke()).

+4

Algo que me hizo tropezar por un minuto o dos ... Si su código está en el espacio de nombres, asegúrese de escapar \ Closure para volver al espacio de nombres global. – Jim

+7

No es necesario hacer 'is_object ($ t)', al hacer 'instanceof' para un objeto no siempre se devolverá falso. –

13

Creo que puede usar instanceof Closure aunque el manual indica que esto no se debe confiar. Supongo que funciona por ahora.

Las funciones anónimas se implementan actualmente utilizando la clase Cierre. Este es un detalle de implementación y no se debe confiar en él.

actualización El Cierre manual page ha actualizado su orientación sobre esto. Parece que ahora se puede confiar en este comportamiento.

funciones anónimas, implementados en PHP 5.3, objetos de rendimiento de este tipo. Este hecho solía considerarse un detalle de implementación, pero ahora se puede confiar en él.

+0

@mario me ganó, pero lo dejaré aquí para obtener información adicional (a menos que Mario quiera unir esto con su respuesta) – Phil

2

php.net sugiere el uso de las reflexiones de averiguar si la variable contiene un cierre válida o no

utilizo este pequeño ayudante

function isClosure($suspected_closure) { 
    $reflection = new ReflectionFunction($suspected_closure); 

    return (bool) $reflection->isClosure(); 
} 
0

Si obtiene un error acerca de que no existe ReflectionFunction, use barra diagonal inversa antes de la clase:

// Closure 
$closure = function() {}; 
$reflection = new \ReflectionFunction($closure); 
// checkout if it is a closure 
$test->isTrue($reflection->isClosure()); 
Cuestiones relacionadas