Is callable: примеры (PHP)

Проверка вызываемости: использование 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)
Использование параметра $syntax_only
// Проверка только синтаксиса, метод не существует
$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 существуют другие функции для проверки доступности вызова:

function_exists()

Проверяет существование глобальной функции. Не работает с методами классов или замыканиями.

var_dump(function_exists('strlen')); // true
var_dump(function_exists([$obj, 'method'])); // false
method_exists()

Проверяет существование метода в классе или объекте. Не проверяет его доступность для вызова (например, private метод извне).

class Test {
    private function privateMethod() {}
}
$t = new Test();
var_dump(method_exists($t, 'privateMethod')); // true
var_dump(is_callable([$t, 'privateMethod'])); // false

is_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)
Проверка private и protected методов

Функция учитывает контекст вызова. Проверка приватного метода извне вернет 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()); // true
bool(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().

Пример php
class InvokableClass {
    public function __invoke() {
        echo 'Object called as function';
    }
}
$obj = new InvokableClass();
$result = is_callable($obj);
var_dump($result);
bool(true)
Использование с замыканиями

Анонимные функции всегда являются вызываемыми.

Пример php
$closure = function() { return 42; };
$result = is_callable($closure);
var_dump($result);
bool(true)
Магические методы

Проверка магических методов, таких как __callStatic, также возможна.

Пример php
class MagicClass {
    public static function __callStatic($name, $arguments) {
        echo 'Static method ' . $name . ' called';
    }
}
$result = is_callable(['MagicClass', 'undefinedStaticMethod']);
var_dump($result);
bool(true)
Динамические имена функций

Полезно для реализации плагинов или динамических вызовов.

Пример php
$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 методы.

Пример php
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); // true

Is callable в Python

Используют функцию callable() или проверку типа:

print(callable(len))  # True
print(callable('str'))  # False
# Альтернатива
import types
print(isinstance(len, types.FunctionType))  # True

Is callable в MySQL

Прямых аналогов нет, так как SQL — язык запросов, а не процедурного программирования. Существуют хранимые процедуры и функции, но их проверка — это проверка существования в метаданных.

-- Проверка существования функции
SELECT ROUTINE_NAME FROM INFORMATION_SCHEMA.ROUTINES 
WHERE ROUTINE_TYPE='FUNCTION' AND ROUTINE_NAME='my_function';

Главное отличие PHP-функции — возможность проверки сложных структур (массивов) и методов с учетом видимости.

PHP is_callable function comments

En
Is callable Verify that a value can be called as a function from the current scope.