2012-06-02 18 views
12

decir que tengo una matriz como sigue:¿Alguna manera de verificar funciones anónimas?

array(
    [0] => function() { return "hello"; } 
    [1] => function() { return "world"; } 
    [2] => "look" 
    [3] => function() { return "and";} 
    [4] => function() { return "listen";} 
) 

¿Hay alguna manera de invocar a 0, 1, 3 y 4 sin invocar 2?

+8

instanceof Closure && is_callable() – jolt

+0

¿No debería ser esta una respuesta? – elite5472

+0

Escribió desde el teléfono, no quería hacer la parte de formateo. SO no es amigable para dispositivos móviles. :( – jolt

Respuesta

16

funciones anónimas son instancias de la clase Closure. Entonces, verificar eso y is_callable hace el trabajo.

foreach ($array as $func) { 
    if (is_callable($func) && $func instanceof Closure) { 
     $func(); 
    } 
} 

En realidad, la comprobación de clase debe ser suficiente ya que no se puede crear una instancia Closure objetos manualmente, excepto mediante la creación de una función anónima.

+0

Esto funciona genial. – elite5472

+0

@ elite5472 lo has probado? debería causar un error fatal si '" look "' se define como una función porque conducirá a la prueba '" look "instanceof Closure' que causa un error fatal. Lols, no importa, eso es solo si prueba una cadena directamente en lugar de una variable que contiene una cadena ...: D – Esailija

+0

Esailija, no, lleva a probar '$ func instanceof Closure' que es válido:' $ func = 'look' ; var_dump ($ func instanceof Closure); '=>' bool (false) ' –

1

Puede usar reflection, tiene an undocument function to check for closures; intente esto (no se han probado):

foreach ($array as $val) { 
    $re = newReflectionFunction($val); 
    if ($re->isClosure()) { 
     $val(); 
     // do whatever you want 
    } 
} 

... o compruebe si no es una cadena/numérico:

foreach ($array as $val) { 
    if (!is_string($val) && !is_numeric($val)) { 
     $val(); 
     // do whatever you want 
    } 
} 

... o comprobar si se trata de un objeto:

foreach ($array as $val) { 
    if (gettype($val) == 'object') { 
     $val(); 
     // do whatever you want 
    } 
} 
+0

Esto no es muy útil. ¿Qué pasa si no es una cadena? – elite5472

+0

En su caso, así es, asumí que era una función anónima o una cadena. – Jeroen

+1

elite5472, eso no es lo que preguntaste. De su pregunta, una respuesta igual de útil sería 'if ($ val! == 'look') ...' –

0

gettype en métodos anon volver "objeto" y is_callable() devuelve true en funciones, a continuación:

foreach ($array as $val) { 
    if (is_callable($val) && gettype($val)=="object") { 
     $val(); 
    } 
} 

y aquí es mi código de prueba:

<?php 

function look(){ 
    return "looking"; 
} 

$data=array(
    0 => function() { return "hello"; }, 
    1 => function() { return "world"; }, 
    2 => "look", 
    3 => function() { return "and";}, 
    4 => function() { return "listen";} 
); 
echo "<pre>"; 

foreach ($data as $val) { 
    if (is_callable($val) && gettype($val)=="object") { 
     echo $val(); 
    } 
} 

?> 
+0

¿Qué sucede si 'look()' es una función definida? –

+0

Actualicé mi respuesta. –

+0

Esto no es correcto, porque [__invoke] (http://www.php.net/manual/en/language.oop5.magic.php#object.invoke)() existe, por lo que cualquier objeto definido por el usuario se puede crear invocable – goat

1

Creo que esto es lo que quieres. $result será una matriz del valor de retorno de cada llamada de función (excepto si no es una función anónima, en cuyo caso será el valor original desde $array).

$result = array_map(
        function($e) { 
         return ($e instanceof Closure && is_callable($e)) ? 
         $e() : $e; 
        }, $array); 
Cuestiones relacionadas