php is_function () per determinare se una variabile è una funzione


88

Ero piuttosto entusiasta di leggere delle funzioni anonime in php, che ti consentono di dichiarare una variabile che è una funzione più semplice di quanto potresti fare con create_function . Ora mi chiedo se ho una funzione a cui viene passata una variabile, come posso controllarla per determinare se si tratta di una funzione? Non esiste ancora una funzione is_function () e quando eseguo un var_dump di una variabile che è una funzione:

$func = function(){
    echo 'asdf';
};
var_dump($func);

Ho capito:

object(Closure)#8 (0) { } 

Qualche idea su come verificare se questa è una funzione?

Risposte:


139

Utilizzare is_callableper determinare se una determinata variabile è una funzione. Per esempio:

$func = function()
{  
    echo 'asdf';  
};

if( is_callable( $func ) )
{
    // Will be true.
}

10
is_callable () funzionerà alla grande se stai passando una funzione anonima, un nome di funzione come stringa o un array di callback PHP valido. Se vuoi specificamente controllare solo le funzioni anonime, allora vorresti qualcosa di simile a quello che ha detto Gumbo: assicurati che il parametro sia un oggetto e assicurati che sia un'istanza di Closure.
Lane

2
E se volessi controllare se si tratta di un callack o di una stringa e fare cose diverse per loro. Non voglio che un valore di stringa venga preso accidentalmente come callback.
Gherman

2
@German Controlla prima se is_string ($ func) poi come secondo controlla is_callable ($ func)
Heroselohim

4
Lo snippet di codice sopra mi ha messo nei guai. Volevo una stringa etichettata "Data" ed è stata quindi gestita come una chiusura ed eseguita. Il modo corretto è if (($ variable instanceof Closure) && is_callable ($ variable)) {...}
Basil Musa

1
Perché l'istanza di chiusura AND è richiamabile. Quando una chiusura non è richiamabile? Non sarei sorpreso se ci fosse un tempo, ma sono curioso di sapere perché abbiamo bisogno di entrambi i controlli.
Joel M

34

È possibile utilizzare function_existsper verificare che sia presente una funzione con il nome specificato. E per combinarlo con funzioni anonime, prova questo:

function is_function($f) {
    return (is_string($f) && function_exists($f)) || (is_object($f) && ($f instanceof Closure));
}

Grazie per questo! La mia app consente agli utenti di specificare la propria funzione di hashing o in alternativa di fornire un argomento per hash (). Ma alcuni degli algoritmi di hashing validi sono anche incorporati PHP e quindi richiamabili ('md5', 'sha1' per esempio). is_object()ed instanceof Closureè un modo molto più affidabile per verificarlo!
njbair

Rimuovere le chiamate is_string e function_exists e questa è la funzione che si desidera utilizzare per rilevare le funzioni lambda. Grazie!
jack

28

Se vuoi solo controllare se una variabile è una funzione anonima e non una stringa o un array richiamabile, usa instanceof.

$func = function()
{  
    echo 'asdf';  
};

if($func instanceof Closure)
{
    // Will be true.
}

Le funzioni anonime (del tipo che sono state aggiunte in PHP 5.3) sono sempre istanze della Closureclasse e ogni istanza diClosure classe è una funzione anonima.

C'è un altro tipo di cosa in PHP che potrebbe essere considerata una funzione, e sono gli oggetti che implementano il __invokemetodo magico. Se vuoi includerli (escludendo comunque stringhe e array), usa method_exists($func, '__invoke'). Ciò includerà ancora le chiusure, poiché le chiusure vengono implementate __invokeper coerenza.


8
Ciò è particolarmente utile, perché is_callable()proverà a trovare un metodo da chiamare in base a una stringa o un array passato, che potrebbe caricare automaticamente le classi e potrebbe non essere il comportamento che ti aspetti / richiedi.
spikyjt

2
function is_function($f) {
    return is_callable($f) && !is_string($f);
}

In futuro, PHP potrebbe cambiare gettype () da Object a Callable, come già fanno altri linguaggi. Quindi, questa risposta è probabilmente il modo migliore per andare. Ma questo può essere ottimizzato come: return! Is_string ($ f) &&! Is_array ($ f) && is_callable ($ f).
Alexandre T.

0

In php i callables validi possono essere funzioni, nome di funzioni (stringhe) e array dei form ['className', 'staticMethod']oppure [$object, 'method'], quindi per rilevare solo le funzioni è necessario escludere stringhe e array:

function isFunction($callable) {
    return $callable && !is_string($callable) && !is_array($callable) && is_callable($callable);
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.