php is_function (), чтобы определить, является ли переменная функцией

89

Я был очень взволнован, прочитав об анонимных функциях в php, которые позволяют вам объявлять переменную, которая является функцией, проще, чем вы могли бы сделать с помощью create_function . Теперь мне интересно, есть ли у меня функция, которой передается переменная, как я могу проверить ее, чтобы определить, является ли это функцией? Еще нет функции is_function (), и когда я делаю var_dump переменной, которая является функцией ::

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

Я получаю это:

object(Closure)#8 (0) { } 

Есть мысли о том, как проверить, является ли это функцией?

Jage
источник

Ответы:

142

Используется, is_callableчтобы определить, является ли данная переменная функцией. Например:

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

if( is_callable( $func ) )
{
    // Will be true.
}
Джон Бенедикто
источник
10
is_callable () отлично работает независимо от того, передаете ли вы анонимную функцию, имя функции в виде строки или действительный массив обратного вызова PHP. Если вы специально хотите проверить только анонимные функции, вам нужно что-то вроде того, что сказал Гамбо: убедитесь, что параметр является объектом, и убедитесь, что это экземпляр Closure.
Lane
2
Что, если я захочу проверить, это callack или строка, и сделать для них разные вещи. Я не хочу, чтобы строковое значение было случайно использовано в качестве обратного вызова.
Gherman
3
@German Просто сначала проверьте, is_string ($ func), а затем, как вторую, проверьте с помощью is_callable ($ func)
Героселохим
4
Приведенный выше фрагмент кода доставил мне неприятности. Я задумал строку с надписью «Дата», которая затем была обработана как закрытие и выполнена. Правильный способ - if (($ variable instanceof Closure) && is_callable ($ variable)) {...}
Бэзил Муса
1
Почему экземпляр закрытия AND вызывается. Когда закрытие нельзя отозвать? Не удивлюсь, если будет время, но мне любопытно, зачем нам нужны оба чека.
Джоэл М.
34

Вы можете использовать, function_existsчтобы проверить, есть ли функция с заданным именем. И чтобы совместить это с анонимными функциями, попробуйте следующее:

function is_function($f) {
    return (is_string($f) && function_exists($f)) || (is_object($f) && ($f instanceof Closure));
}
Гамбо
источник
Спасибо за это! Мое приложение позволяет пользователям указывать свою собственную функцию хеширования или, альтернативно, предоставлять аргумент для hash (). Но некоторые из действующих алгоритмов хеширования также являются встроенными в PHP и, следовательно, вызываемыми (например, 'md5', 'sha1'). is_object()и instanceof Closureэто гораздо более надежный способ проверить это!
njbair
Удалите вызовы is_string и function_exists, и это функция, которую вы хотите использовать для обнаружения лямбда-функций. Спасибо!
jack
30

Если вы хотите только проверить, является ли переменная анонимной функцией, а не вызываемой строкой или массивом, используйте instanceof.

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

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

Анонимные функции (того типа, который был добавлен в PHP 5.3) всегда являются экземплярами Closureкласса, и каждый экземпляр Closureкласса является анонимной функцией.

В PHP есть еще один тип вещей, которые можно было бы рассматривать как функцию, и это объекты, реализующие __invokeмагический метод. Если вы хотите включить их (исключая строки и массивы), используйте method_exists($func, '__invoke'). Это по-прежнему будет включать в себя замыкания, поскольку замыкания реализованы __invokeдля согласованности.

Brilliand
источник
8
Это особенно полезно, потому что is_callable()будет пытаться найти метод для вызова на основе переданной строки или массива, который может автоматически загружать классы и может не соответствовать ожидаемому / требуемому поведению.
spikyjt
2
function is_function($f) {
    return is_callable($f) && !is_string($f);
}
Артемий СтагнантЛед Алексей
источник
В будущем PHP может изменить gettype () с Object на Callable, как это уже делают другие языки. Итак, этот ответ, вероятно, лучший вариант. Но это можно оптимизировать как: return! Is_string ($ f) &&! Is_array ($ f) && is_callable ($ f).
Александр Т.
0

В php допустимыми вызываемыми объектами могут быть функции, имена функций (строки) и массивы форм ['className', 'staticMethod']или [$object, 'method'], поэтому для обнаружения только функций необходимо исключить строки и массивы:

function isFunction($callable) {
    return $callable && !is_string($callable) && !is_array($callable) && is_callable($callable);
}
Андрей Изман
источник