php is_function (), aby określić, czy zmienna jest funkcją

89

Byłem bardzo podekscytowany czytaniem o anonimowych funkcjach w php, które pozwalają zadeklarować zmienną, która jest funkcją łatwiejszą niż w przypadku create_function . Teraz zastanawiam się, czy mam funkcję, której przekazano zmienną, jak mogę to sprawdzić, aby określić, czy jest to funkcja? Nie ma jeszcze funkcji is_function (), a kiedy wykonuję var_dump zmiennej, która jest funkcją:

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

Rozumiem:

object(Closure)#8 (0) { } 

Jakieś przemyślenia, jak sprawdzić, czy to jest funkcja?

Jage
źródło

Odpowiedzi:

142

Służy is_callabledo określania, czy dana zmienna jest funkcją. Na przykład:

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

if( is_callable( $func ) )
{
    // Will be true.
}
Jon Benedicto
źródło
10
is_callable () będzie działać świetnie, niezależnie od tego, czy przekazujesz anonimową funkcję, nazwę funkcji jako ciąg, czy prawidłową tablicę wywołań zwrotnych PHP. Jeśli chcesz sprawdzić tylko funkcje anonimowe, chciałbyś czegoś takiego, jak powiedział Gumbo: upewnij się, że parametr jest obiektem i upewnij się, że jest to wystąpienie Closure.
Lane
2
A co jeśli chcę sprawdzić, czy to callack czy sznurek i zrobić dla nich różne rzeczy. Nie chcę, aby wartość ciągu została przypadkowo odebrana jako wywołanie zwrotne.
Gherman,
3
@German prostu sprawdzić najpierw, czy is_string ($ func), a następnie jako drugi czeka z is_callable ($ func)
Heroselohim
4
Powyższy fragment kodu wpędził mnie w kłopoty. Zamierzałem napisać napis „Date”, a następnie potraktowano go jako zamknięcie i wykonano. Prawidłowy sposób to if (($ variable instanceof Closure) && is_callable ($ variable)) {...}
Basil Musa,
1
Dlaczego wystąpienie zamknięcia AND jest wywoływalne. Kiedy zamknięcie nie jest możliwe? Nie zdziwiłbym się, gdyby był czas, ale jestem ciekaw, dlaczego potrzebujemy obu czeków.
Joel M
34

Możesz użyć, function_existsaby sprawdzić, czy istnieje funkcja o podanej nazwie. Aby połączyć to z anonimowymi funkcjami, spróbuj tego:

function is_function($f) {
    return (is_string($f) && function_exists($f)) || (is_object($f) && ($f instanceof Closure));
}
Gumbo
źródło
Dzięki za to! Moja aplikacja umożliwia użytkownikom określenie własnej funkcji haszującej lub alternatywnie podanie argumentu funkcji hash (). Ale niektóre z prawidłowych algorytmów haszujących są również wbudowane w PHP, a zatem można je wywołać (na przykład „md5”, „sha1”). is_object()i instanceof Closurejest znacznie bardziej niezawodnym sposobem sprawdzenia tego!
njbair
Usuń wywołania is_string i function_exists, a to jest funkcja, której chcesz użyć do wykrywania funkcji lambda. Dziękuję Ci!
jack
30

Jeśli chcesz tylko sprawdzić, czy zmienna jest funkcją anonimową, a nie ciągiem lub tablicą możliwą do wywołania, użyj instanceof.

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

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

Funkcje anonimowe (takie, jakie zostały dodane w PHP 5.3) są zawsze instancjami Closureklasy, a każda instancja Closureklasy jest funkcją anonimową.

W PHP jest jeszcze jeden rodzaj rzeczy, które można by prawdopodobnie uznać za funkcję, a są to obiekty implementujące __invokemagiczną metodę. Jeśli chcesz je uwzględnić (jednocześnie wykluczając ciągi i tablice), użyj method_exists($func, '__invoke'). Będzie to nadal obejmować zamknięcia, ponieważ zamknięcia są wdrażane w __invokecelu zachowania spójności.

Brilliand
źródło
8
Jest to szczególnie przydatne, ponieważ is_callable()spróbuje znaleźć metodę do wywołania na podstawie przekazanego ciągu lub tablicy, która może automatycznie ładować klasy i może nie być zachowaniem, którego oczekujesz / wymagasz.
spikyjt
2
function is_function($f) {
    return is_callable($f) && !is_string($f);
}
Artemiy StagnantIce Alexeew
źródło
W przyszłości PHP może zmienić gettype () z Object na Callable, tak jak inne języki już to robią. Tak więc ta odpowiedź jest prawdopodobnie najlepszą drogą. Ale można to zoptymalizować jako: return! Is_string ($ f) &&! Is_array ($ f) && is_callable ($ f).
Alexandre T.
0

W php poprawnymi wywoływanymi mogą być funkcje, nazwy funkcji (ciągi znaków) i tablice formularzy ['className', 'staticMethod']lub [$object, 'method'], aby wykryć tylko funkcje, należy wykluczyć ciągi i tablice:

function isFunction($callable) {
    return $callable && !is_string($callable) && !is_array($callable) && is_callable($callable);
}
Andrey Izman
źródło