php is_function () para determinar se uma variável é uma função

88

Fiquei muito animado ao ler sobre funções anônimas em php, que permitem declarar uma variável que é função mais fácil do que você faria com create_function . Agora estou me perguntando se tenho uma função que é passada uma variável, como posso verificá-la para determinar se é uma função? Não há função is_function () ainda, e quando eu faço um var_dump de uma variável que é uma função ::

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

Eu entendi isso:

object(Closure)#8 (0) { } 

Alguma ideia de como verificar se esta é uma função?

Jage
fonte

Respostas:

139

Use is_callablepara determinar se uma determinada variável é uma função. Por exemplo:

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

if( is_callable( $func ) )
{
    // Will be true.
}
Jon Benedicto
fonte
10
is_callable () funcionará muito bem se você estiver passando uma função anônima, um nome de função como uma string ou um array de retorno de chamada PHP válido. Se você deseja verificar especificamente apenas funções anônimas, deve fazer algo parecido com o que Gumbo disse: certifique-se de que o parâmetro seja um objeto e de que seja uma instância de Closure.
Lane
2
E se eu quiser verificar se é um callack ou uma string e fazer coisas diferentes para eles. Não quero que um valor de string seja acidentalmente considerado um retorno de chamada.
Gherman
2
@German Basta verificar primeiro se is_string ($ func) e, em seguida, verificar com is_callable ($ func)
Heroselohim
4
O trecho de código acima me colocou em apuros. Eu pretendia uma string rotulada "Data" e ela foi então tratada como um encerramento e executada. A maneira correta é if (($ variable instanceof Closure) && is_callable ($ variable)) {...}
Basil Musa
1
Por que a instância de encerramento AND pode ser chamada. Quando um encerramento não pode ser resgatado? Não ficaria surpreso se houvesse um tempo, mas estou curioso para saber por que precisamos dos dois cheques.
Joel M
34

Você pode usar function_existspara verificar se há uma função com o nome fornecido. E para combinar isso com funções anônimas, tente o seguinte:

function is_function($f) {
    return (is_string($f) && function_exists($f)) || (is_object($f) && ($f instanceof Closure));
}
quiabo
fonte
Obrigado por isso! Meu aplicativo permite que os usuários especifiquem sua própria função de hash ou, como alternativa, forneçam um argumento para hash (). Mas alguns dos algoritmos de hash válidos também são internos do PHP e, portanto, podem ser chamados ('md5', 'sha1' por exemplo). is_object()e instanceof Closureé uma maneira muito mais robusta de verificar isso!
njbair
Remova as chamadas is_string e function_exists e esta é a função que você deseja usar para detectar funções lambda. Obrigado!
jack
28

Se você deseja apenas verificar se uma variável é uma função anônima e não uma string ou array chamável, use instanceof.

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

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

Funções anônimas (do tipo que foram adicionadas no PHP 5.3) são sempre instâncias da Closureclasse, e cada instância da Closureclasse é uma função anônima.

Existe outro tipo de coisa em PHP que pode ser considerada uma função, e são os objetos que implementam o __invokemétodo mágico. Se quiser incluí-los (enquanto exclui strings e matrizes), use method_exists($func, '__invoke'). Isso ainda incluirá fechamentos, uma vez que os fechamentos implementam __invokepara consistência.

Brilliand
fonte
8
Isso é particularmente útil, porque is_callable()tentará encontrar um método para chamar com base em uma string ou array passado, que pode carregar classes automaticamente e pode não ser o comportamento que você espera / requer.
spikyjt
2
function is_function($f) {
    return is_callable($f) && !is_string($f);
}
Artemiy StagnantIce Alexeew
fonte
No futuro, o PHP pode mudar gettype () de Object para Callable, como outras linguagens já fazem. Portanto, esta resposta é provavelmente o melhor caminho a seguir. Mas isso pode ser otimizado como: return! Is_string ($ f) &&! Is_array ($ f) && is_callable ($ f).
Alexandre T.
0

Em php, os callables válidos podem ser funções, nome de funções (strings) e arrays dos formulários ['className', 'staticMethod']ou [$object, 'method'], para detectar apenas funções, é necessário excluir strings e arrays:

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