Il PHP manual for anonymous functions (cioè, chiusure) stabilisce che:Test di PHP Chiusura senza riferimento alla classe interna Chiusura
funzioni anonime sono attualmente implementati utilizzando la classe di chiusura. Questo è un dettaglio di implementazione e non dovrebbe essere invocato su.
(L'enfasi è mia)
E 'possibile testare una variabile, in modo che il test restituisce vero solo se la variabile è una chiusura, senza fare riferimento alla classe di chiusura?
In altre parole, come posso riscrivere la seguente modo tale che esso genera un errore quando $bar
è tutt'altro che una funzione anonima:
function foo(Closure $bar) { $bar(); }
EDIT: Sulla base delle risposte ricevute, qui è un test di esempio .
Note:
- sembra che ci sia alcun modo per distinguere tra Funtori e chiusure, e che il test è probabilmente altrettanto 'implementazione specifica' come utilizzando la classe di chiusura.
- Il metodo (apparentemente ovvio)
ReflectionFunction::isClosure()
sembra essere quasi inutile: dal momento in cui sono stati eseguiti i controlli necessari per assicurarsi che ReflectionFunction possa effettivamente essere istanziato (non può prendere una classe tranne che per una chiusura), hai eliminato tutte le altre opzioni. - In 5.3.0 si ReflectionClass ($ closure) -> hasMethod ('__ invoke') ha restituito false, quindi questo potrebbe essere utilizzato come test contro Functors, tuttavia (mi è stato detto) questo è cambiato da allora. Ciò evidenzia anche la fragilità della soluzione.
- seguito riservato alle Gordon - Dal PHP 5.4 si può contare su di chiusura essendo una chiusura: php.net/manual/en/class.closure.php
Codice: caso
/**
* Return true if and only if the passed argument is a Closure.
*/
function testClosure($a) {
// Must be Callback, Labmda, Functor or Closure:
if(!is_callable($a)) return false;
// Elminate Callbacks & Lambdas
if(!is_object($a)) return false;
// Eliminate Functors
//$r = new ReflectionFunction($a); <-- fails if $a is a Functor
//if($r->isClosure()) return true;
return false;
}
prova:
//////////// TEST CASE /////////////
class CallBackClass {
function callBackFunc() {
}
}
class Functor {
function __invoke() {
}
}
$functor = new Functor();
$lambda = create_function('', '');
$callback = array('CallBackClass', 'callBackFunc');
$array = array();
$object = new stdClass();
$closure = function() { ; };
echo "Is it a closure? \n";
echo "Closure: " . (testClosure($closure) ? "yes" : "no") . "\n";
echo "Null: " . (testClosure(null) ? "yes" : "no") . "\n";
echo "Array: " . (testClosure($array) ? "yes" : "no") . "\n";
echo "Callback: " . (testClosure($callback) ? "yes" : "no") . "\n";
echo "Labmda: " .(testClosure($lambda) ? "yes" : "no") . "\n";
echo "Invoked Class: " . (testClosure($functor) ? "yes" : "no") . "\n";
echo "StdObj: " . (testClosure($object) ? "yes" : "no") . "\n";
-
Che dire funzioni create utilizzando 'create_function', funzioni anonime del povero da prima PHP 5.3? Che dire degli oggetti che possono essere '__invoke()' d? – janmoesen
Sono particolarmente interessato a verificare se è possibile eseguire una chiusura ("... restituisce true solo se la variabile è una chiusura ...") – Hamish
La mia domanda è perché si desidera distinguere tra un functor (o qualsiasi callback a quel punto) e una chiusura? In 5.3, non c'è differenza dal tuo punto di vista (dal momento che non puoi riassociare nulla), quindi che importa? Se passa 'is_callable()', allora perché non è abbastanza ??? – ircmaxell