php is_function () pour déterminer si une variable est une fonction

88

J'étais très excité de lire sur les fonctions anonymes en php, qui vous permettent de déclarer une variable qui fonctionne plus facilement que vous ne pourriez le faire avec create_function . Maintenant, je me demande si j'ai une fonction à laquelle une variable est passée, comment puis-je la vérifier pour déterminer si c'est une fonction? Il n'y a pas encore de fonction is_function (), et quand je fais un var_dump d'une variable qui est une fonction:

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

J'ai compris:

object(Closure)#8 (0) { } 

Des réflexions sur la façon de vérifier s'il s'agit d'une fonction?

Jage
la source

Réponses:

139

Permet is_callablede déterminer si une variable donnée est une fonction. Par exemple:

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

if( is_callable( $func ) )
{
    // Will be true.
}
Jon Benedicto
la source
10
is_callable () fonctionnera très bien que vous passiez une fonction anonyme, un nom de fonction sous forme de chaîne ou un tableau de rappel PHP valide. Si vous souhaitez spécifiquement vérifier uniquement les fonctions anonymes, vous voudrez quelque chose comme ce que Gumbo a dit: assurez-vous que le paramètre est un objet et assurez-vous qu'il s'agit d'une instance de Closure.
Lane
2
Que faire si je veux vérifier s'il s'agit d'un callack ou d'une chaîne et faire des choses différentes pour eux. Je ne veux pas qu'une valeur de chaîne soit prise accidentellement comme un rappel.
Gherman
2
@Allemand Vérifiez d'abord si is_string ($ func) puis comme deuxième vérification avec is_callable ($ func)
Heroselohim
4
L'extrait de code ci-dessus m'a causé des problèmes. Je voulais une chaîne intitulée "Date" et elle a ensuite été traitée comme une fermeture et exécutée. La bonne façon est if (($ variable instanceof Closure) && is_callable ($ variable)) {...}
Basil Musa
1
Pourquoi l'instance de fermeture AND est appelable. Quand une fermeture n'est-elle pas appelable? Je ne serais pas surpris s'il y avait un temps, mais je suis curieux de savoir pourquoi nous avons besoin des deux chèques.
Joel M
34

Vous pouvez utiliser function_existspour vérifier qu'il existe une fonction avec le nom donné. Et pour combiner cela avec des fonctions anonymes, essayez ceci:

function is_function($f) {
    return (is_string($f) && function_exists($f)) || (is_object($f) && ($f instanceof Closure));
}
Gombo
la source
Merci pour cela! Mon application permet aux utilisateurs de spécifier leur propre fonction de hachage ou de fournir un argument pour hash (). Mais certains des algorithmes de hachage valides sont également intégrés à PHP, et donc appelables ('md5', 'sha1' par exemple). is_object()et instanceof Closurec'est un moyen beaucoup plus robuste de vérifier cela!
njbair
Supprimez les appels is_string et function_exists et c'est la fonction que vous souhaitez utiliser pour détecter les fonctions lambda. Je vous remercie!
jack
28

Si vous souhaitez uniquement vérifier si une variable est une fonction anonyme et non une chaîne ou un tableau appelable, utilisez instanceof.

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

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

Les fonctions anonymes (du type qui ont été ajoutés dans PHP 5.3) sont toujours des instances de la Closureclasse, et chaque instance de la Closureclasse est une fonction anonyme.

Il y a un autre type de chose en PHP qui pourrait sans doute être considéré comme une fonction, et ce sont les objets qui implémentent la __invokeméthode magique. Si vous souhaitez les inclure (tout en excluant les chaînes et les tableaux), utilisez method_exists($func, '__invoke'). Cela inclura toujours les fermetures, puisque les fermetures implémentent la __invokecohérence.

Brilliand
la source
8
Ceci est particulièrement utile, car is_callable()il essaiera de trouver une méthode à appeler basée sur une chaîne ou un tableau passé, qui peut charger automatiquement des classes et peut ne pas être le comportement que vous attendez / exigez.
spikyjt
2
function is_function($f) {
    return is_callable($f) && !is_string($f);
}
Artemiy StagnantIce Alexeew
la source
À l'avenir, PHP pourrait changer gettype () d'Object en Callable, comme le font déjà d'autres langages. Donc, cette réponse est probablement la meilleure voie à suivre. Mais cela peut être optimisé comme: return! Is_string ($ f) &&! Is_array ($ f) && is_callable ($ f).
Alexandre T.
0

En php, les appelables valides peuvent être des fonctions, le nom des fonctions (chaînes) et des tableaux des formulaires ['className', 'staticMethod']ou [$object, 'method'], pour détecter, seules les fonctions doivent exclure les chaînes et les tableaux:

function isFunction($callable) {
    return $callable && !is_string($callable) && !is_array($callable) && is_callable($callable);
}
Andrey Izman
la source