2012-06-02 14 views
12

Supponiamo di avere una matrice come segue:Un modo per controllare le funzioni anonime?

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

C'è un modo per invocare 0, 1, 3 e 4 senza invocare 2?

+8

instanceof Closure && is_callable() – jolt

+0

Questa non dovrebbe essere una risposta? – elite5472

+0

Scritto dal telefono, non voleva eseguire la parte di formattazione. SO non è mobile-friendly. :( – jolt

risposta

16

funzioni anonime sono istanze della classe Closure. Quindi controllando che e is_callable fa il lavoro.

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

In realtà, il controllo di classe dovrebbe essere sufficiente dal momento che non è possibile creare un'istanza Closure oggetti manualmente se non con la creazione di una funzione anonima.

+0

Funziona alla grande. – elite5472

+0

@ elite5472 lo hai provato? dovrebbe causare un errore fatale se "look" è definito come una funzione perché porterà a test "look" instanceof Closure' che causa un errore fatale. Lol, non importa, questo è solo se testate direttamente una stringa invece di una variabile contenente una stringa ...: D – Esailija

+0

Esailija, no, porta a testare '$ func instancef Closure' che è valida:' $ func = 'look' ; var_dump ($ func instanceof Closure); '=>' bool (false) ' –

1

È possibile utilizzare reflection, ha an undocument function to check for closures; provate questo (non hanno testato):

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

... o controllare se non è una stringa/numerica:

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

... o controllare se si tratta di un oggetto:

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

Questo non è molto utile. Cosa succede se non è una stringa? – elite5472

+0

Nel tuo caso lo è, quindi supponevo che fosse una funzione anonima o una stringa. – Jeroen

+1

elite5472, non è quello che hai chiesto. Dalla tua domanda, una risposta altrettanto utile sarebbe 'if ($ val! == 'look') ...' –

0

gettype sui metodi anon ritorno "oggetto" e is_callable() restituisce true sulle funzioni, quindi:

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

ed ecco il mio codice di prova:

<?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

Cosa succede se 'look()' è una funzione definita? –

+0

Ho aggiornato la mia risposta. –

+0

Questo non è corretto, perché [__invoke] (http://www.php.net/manual/en/language.oop5.magic.php#object.invoke)() esiste e quindi qualsiasi oggetto definito dall'utente può essere fatto callable. – goat

1

Penso che questo sia quello che vuoi. $result sarà una matrice del valore di ritorno di ogni chiamata di funzione (eccetto se non è una funzione anonima, nel qual caso sarà il valore originale da $array).

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