php is_function() para determinar si una variable es una función

4 minutos de lectura

Estaba muy emocionada de leer sobre funciones anónimas en php, que le permite declarar una variable que funciona más fácilmente de lo que podría hacerlo con crear_funcion. Ahora me pregunto si tengo una función a la que se le pasa una variable, ¿cómo puedo verificarla para determinar si es una función? Todavía no hay una función is_function(), y cuando hago un var_dump de una variable que es una función:

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

Entiendo esto:

object(Closure)#8 (0) { } 

¿Alguna idea sobre cómo comprobar si se trata de una función?

avatar de usuario
Jon Benedicto

Usar is_callable para determinar si una variable dada es una función. Por ejemplo:

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

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

  • is_callable() funcionará muy bien ya sea que esté pasando una función anónima, un nombre de función como una cadena o una matriz de devolución de llamada de PHP válida. Si desea verificar específicamente solo las funciones anónimas, entonces querrá algo como lo que dijo Gumbo: asegúrese de que el parámetro sea un objeto y asegúrese de que sea una instancia de Closure.

    – Carril

    3 de noviembre de 2011 a las 16:21


  • ¿Qué sucede si quiero verificar si es un callack o una cadena y hacer cosas diferentes para ellos? No quiero que un valor de cadena se tome accidentalmente como una devolución de llamada.

    – Gherman

    19 de agosto de 2014 a las 11:26

  • @Alemán Solo verifique primero si is_string ($ func) y luego como segundo control con is_callable ($ func)

    – Heroselohim

    08/01/2015 a las 21:48

  • El fragmento de código anterior me metió en problemas. Tenía la intención de una cadena etiquetada como “Fecha” y luego se manejó como un cierre y se ejecutó. La forma correcta es si (($variable instancia de Closure) && is_callable($variable)) {…}

    – Albahaca Musa

    18 de diciembre de 2015 a las 12:21

  • Por qué la instancia de cierre AND es invocable. ¿Cuándo un cierre no es exigible? No me sorprendería si hubiera un tiempo, pero tengo curiosidad por qué necesitamos ambos cheques.

    – Joel M.

    1 de enero de 2020 a las 1:46

Puedes usar function_exists para comprobar que hay una función con el nombre dado. Y para combinar eso con funciones anónimas, intente esto:

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

  • ¡Gracias por esto! Mi aplicación permite a los usuarios especificar su propia función hash o, alternativamente, proporcionar un argumento para hash(). Pero algunos de los algoritmos hash válidos también son incorporados en PHP y, por lo tanto, se pueden llamar (‘md5’, ‘sha1’, por ejemplo). is_object() y instanceof Closure ¡Es una forma mucho más robusta de verificar esto!

    – njbair

    22 de diciembre de 2012 a las 18:50


  • Elimine las llamadas is_string y function_exists y esta es la función que desea usar para detectar funciones lambda. ¡Gracias!

    – Jack

    10 de septiembre de 2013 a las 13:22

  • @njbair Estoy seguro de que ha pensado en esto, pero ¿qué pasa si alguien especifica algo malicioso en su propia función hash?

    – Enigma Plus

    11 de marzo de 2021 a las 10:20

  • @EnigmaPlus Honestamente, no tengo idea de en qué estaba trabajando en ese momento, pero deduzco que estaba trabajando en una biblioteca, no en una aplicación, y que la función hash se especificaría en el código, no a través de la interfaz por un extremo. usuario.

    – njbair

    12 de marzo de 2021 a las 14:35

Si solo desea verificar si una variable es una función anónima y no una cadena o matriz invocable, use instanceof.

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

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

Las funciones anónimas (del tipo que se agregaron en PHP 5.3) son siempre instancias del Closure clase, y cada instancia de la Closure La clase es una función anónima.

Hay otro tipo de cosas en PHP que posiblemente podrían considerarse una función, y son objetos que implementan el __invoke método mágico. Si desea incluirlos (mientras aún excluye cadenas y matrices), use method_exists($func, '__invoke'). Esto aún incluirá cierres, ya que los cierres implementan __invoke por consistencia.

  • Esto es particularmente útil, porque is_callable() intentará encontrar un método para llamar en función de una cadena o matriz pasada, que puede cargar automáticamente las clases y puede no ser el comportamiento que espera/requiere.

    – spikyjt

    16 de febrero de 2015 a las 10:12

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

avatar de usuario
Andrei Izman

En php, las llamadas válidas pueden ser funciones, nombres de funciones (cadenas) y matrices de formularios. ['className', 'staticMethod'] o [$object, 'method']por lo que para detectar solo las funciones deben excluir cadenas y matrices:

function isFunction($callable) {
    return $callable && !is_string($callable) && !is_array($callable) && is_callable($callable);
}

¿Ha sido útil esta solución?