2011-08-18 15 views
20

Usando la seguente funzione:determinare, se una variabile è una chiusura valida in PHP

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

Can questo ritorno vale per qualsiasi altra cosa, di una funzione di chiusura anonima? In tal caso, quale sarebbe il modo corretto per determinare se una variabile è una chiusura?

Grazie

+2

Gli oggetti sono anche richiamabili se implementano ['__invoke'] (http://www.php.net/manual/en/language.oop5.magic.php#language.oop5.magic.invoke). – mario

risposta

40

Il modo più deterministico per verificare se un callback è una chiusura reale è:

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

Tutte le funzioni anonime sono rappresentati come oggetti del tipo Closure in PHP. (Che, tornando al commento sopra, capita di implementare il metodo __invoke().)

+4

Qualcosa che mi ha fatto inciampare per un minuto o due ... Se il tuo codice è un namespace, assicurati di uscire \ Closure per tornare allo spazio dei nomi globale. – Jim

+7

Non è necessario fare 'is_object ($ t)', facendo 'instanceof' per un non-oggetto restituirà sempre false. –

13

Penso che si possa usare instanceof Closure sebbene lo stato manual non dovrebbe essere invocato. Immagino che funzioni per ora.

Le funzioni anonime sono attualmente implementate utilizzando la classe Closure. Questo è un dettaglio di implementazione e non dovrebbe essere invocato.

Aggiornamento La chiusura manual page ha aggiornato la sua guida su questo. Sembra che questo comportamento possa ora essere invocato.

Le funzioni anonime, implementate in PHP 5.3, restituiscono oggetti di questo tipo. Questo fatto era considerato un dettaglio di implementazione, ma ora può essere invocato.

+0

@mario mi ha battuto ma lascerò questo qui per le informazioni extra (a meno che Mario voglia unire questo alla sua risposta) – Phil

2

php.net suggerisce di usare riflessioni per capire se la variabile contiene una chiusura valida o meno

uso questo piccolo aiutante

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

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

Se ricevi un errore sul fatto che non esiste ReflectionFunction, utilizza barra rovesciata prima della lezione:

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