Is callable: примеры (PHP)
is_callable(mixed $value, bool $syntax_only = false, string &$callable_name = null): boolФункция is_callable() проверяет, что содержимое переменной может быть вызвано как функция. Она используется для валидации callback-параметров перед их вызовом, предотвращая фатальные ошибки.
Функция применяется в ситуациях, когда код принимает имена функций или методы объектов от пользователя, из конфигурационных файлов или других внешних источников. Проверка позволяет убедиться, что вызов возможен.
Функция принимает до трех параметров:
- $callback (mixed) — проверяемое значение. Может быть строкой с именем функции, массивом вида [объект, 'имя метода'] или ['имя класса', 'статический метод'], анонимной функцией.
- $syntax_only (bool) — необязательный параметр. Если установлен в true, проверяется только синтаксис строки имени функции или метода. Не проверяется существование класса или доступность метода.
- $callable_name (string | null) — необязательный параметр. При передаче переменной по ссыrece в нее будет записано каноническое имя вызываемого элемента. Для методов вернёт имя в формате "ClassName::methodName".
Проверка простой функции:
$result = is_callable('strlen');
var_dump($result);bool(true)
Проверка несуществующей функции:
$result = is_callable('undefined_function');
var_dump($result);bool(false)
class SampleClass {
public function method() {}
}
$obj = new SampleClass();
$result = is_callable([$obj, 'method']);
var_dump($result);bool(true)
// Проверка только синтаксиса, метод не существует
$result = is_callable([$obj, 'fakeMethod'], true);
var_dump($result);bool(true)
// Полная проверка
$result = is_callable([$obj, 'fakeMethod'], false);
var_dump($result);bool(false)
$callableName = '';
$result = is_callable([$obj, 'method'], false, $callableName);
echo $callableName;SampleClass::method
В PHP существуют другие функции для проверки доступности вызова:
Проверяет существование глобальной функции. Не работает с методами классов или замыканиями.
var_dump(function_exists('strlen')); // true
var_dump(function_exists([$obj, 'method'])); // falseПроверяет существование метода в классе или объекте. Не проверяет его доступность для вызова (например, private метод извне).
class Test {
private function privateMethod() {}
}
$t = new Test();
var_dump(method_exists($t, 'privateMethod')); // true
var_dump(is_callable([$t, 'privateMethod'])); // falseis_callable() предпочтительнее, когда нужна комплексная проверка возможности вызова с учетом области видимости. function_exists() и method_exists() полезны для более узких проверок.
Строка вида "Class::method" без указания в массиве воспринимается как глобальная функция, а не метод.
class MyClass {
public static function staticMethod() {}
}
// Неправильно
$result = is_callable('MyClass::staticMethod');
var_dump($result); // До PHP 8 возвращал true, с PHP 8 - false, если функция не определена глобальноbool(false)
Правильный вариант — использовать массив:
$result = is_callable(['MyClass', 'staticMethod']);
var_dump($result);bool(true)
Функция учитывает контекст вызова. Проверка приватного метода извне вернет false.
class TestClass {
private function privateMethod() {}
public function check() {
return is_callable([$this, 'privateMethod']);
}
}
$obj = new TestClass();
var_dump(is_callable([$obj, 'privateMethod'])); // false
var_dump($obj->check()); // truebool(false) bool(true)
В PHP 8 поведение функции было изменено для строк, содержащих "::". Теперь строка "ClassName::methodName" проверяется как вызов статического метода только в синтаксическом режиме ($syntax_only = true). При обычной проверке ($syntax_only = false) такая строка ищется как глобальная функция.
// PHP 7
var_dump(is_callable('MyClass::staticMethod')); // true, если класс и метод существуют
// PHP 8
var_dump(is_callable('MyClass::staticMethod')); // false, если нет глобальной функции с таким именемТакже в PHP 8 улучшена производительность и устранены некоторые несоответствия в работе с магическими методами.
Функция корректно работает с инвариантами вызова, такими как объекты, реализующие __invoke().
class InvokableClass {
public function __invoke() {
echo 'Object called as function';
}
}
$obj = new InvokableClass();
$result = is_callable($obj);
var_dump($result);bool(true)
Анонимные функции всегда являются вызываемыми.
$closure = function() { return 42; };
$result = is_callable($closure);
var_dump($result);bool(true)
Проверка магических методов, таких как __callStatic, также возможна.
class MagicClass {
public static function __callStatic($name, $arguments) {
echo 'Static method ' . $name . ' called';
}
}
$result = is_callable(['MagicClass', 'undefinedStaticMethod']);
var_dump($result);bool(true)
Полезно для реализации плагинов или динамических вызовов.
$functionList = ['strlen', 'array_merge', 'undefinedFunction'];
foreach ($functionList as $function) {
if (is_callable($function)) {
echo $function . ' is callable\n';
} else {
echo $function . ' is NOT callable\n';
}
}strlen is callable array_merge is callable undefinedFunction is NOT callable
Внутри класса можно проверить, что метод может быть вызван для конкретного объекта, учитывая protected и private методы.
class ParentClass {
protected function protectedMethod() {}
}
class ChildClass extends ParentClass {
public function test() {
var_dump(is_callable([$this, 'protectedMethod']));
}
}
$child = new ChildClass();
$child->test();bool(true)
Is callable в Javascript
Оператор typeof или проверка на функцию:
console.log(typeof alert === 'function'); // true
console.log(typeof undefinedFunction === 'function'); // false
// Или
console.log(alert instanceof Function); // trueIs callable в Python
Используют функцию callable() или проверку типа:
print(callable(len)) # True
print(callable('str')) # False
# Альтернатива
import types
print(isinstance(len, types.FunctionType)) # TrueIs callable в MySQL
Прямых аналогов нет, так как SQL — язык запросов, а не процедурного программирования. Существуют хранимые процедуры и функции, но их проверка — это проверка существования в метаданных.
-- Проверка существования функции
SELECT ROUTINE_NAME FROM INFORMATION_SCHEMA.ROUTINES
WHERE ROUTINE_TYPE='FUNCTION' AND ROUTINE_NAME='my_function';Главное отличие PHP-функции — возможность проверки сложных структур (массивов) и методов с учетом видимости.