Callable как выражение или псевдотип, и callback-функции

Тип callback-функций, или функций обратного вызова, в параметрах и значении возврата функций и методов, разрешается объявлять как callable.

Функции наподобие call_user_func() или usort() принимают пользовательские callback-функции как параметры. Callback-функциями бывают как простые функции, так и методы объектов, включая статические методы классов.

Передача callable-выражений

PHP-функция передаётся по имени, как строка. Разрешается передавать встроенные или пользовательские функции, но не языковые конструкции: array(), echo, empty(), eval(), exit(), isset(), list(), print или unset().

Метод объекта (object) передаётся как массив, в котором в элементе с индексом 0 содержится объект, а в элементе с индексом 1 — название метода. Доступ к закрытым и защищённым методам разрешается изнутри класса.

Статические методы класса передаются как массив, в котором в элементе с индексом 0 вместо передачи объекта указывают название класса, или как строка вида 'ClassName::methodName', при этом объект класса не создают.

Кроме пользовательских функций, в callback-параметр разрешается передавать анонимные и стрелочные функции.

Замечание:

Начиная с PHP 8.1.0 анонимные функции разрешается создавать синтаксисом callable-выражений как объектов первого класса.

Объект, в классе которого реализовали магический метод __invoke(), разрешается передавать в callback-параметр.

Пример #1 Примеры callback-функций

<?php

// Пример callback-функции
function my_callback_function()
{
echo
'Привет, мир!';
}

// Пример callback-метода
class MyClass
{
static function
myCallbackMethod()
{
echo
'Привет, мир!';
}
}

// Тип 1: Простой вызов callback-функции
call_user_func('my_callback_function');

// Тип 2: Вызов статического метода класса
call_user_func(array('MyClass', 'myCallbackMethod'));

// Тип 3: Вызов метода объекта класса
$obj = new MyClass();
call_user_func(array($obj, 'myCallbackMethod'));

// Тип 4: Вызов статического метода класса
call_user_func('MyClass::myCallbackMethod');

// Тип 5: Вызов статического метода родственного класса
class A
{
public static function
who()
{
echo
"A\n";
}
}

class
B extends A
{
public static function
who()
{
echo
"B\n";
}
}

call_user_func(array('B', 'parent::who')); // A, устарело, начиная с PHP 8.2.0

// Тип 6: Объекты, классы которых реализуют магический метод __invoke(),
// разрешается передавать как callable-объекты
class C
{
public function
__invoke($name)
{
echo
'Привет ', $name, "\n";
}
}

$c = new C();
call_user_func($c, 'PHP!');

?>

Пример #2 Пример передачи замыкания (объекта класса Closure) в качестве callback-функции

<?php

// Замыкание
$double = function($a) {
return
$a * 2;
};

// Диапазон чисел
$numbers = range(1, 5);

// Передаём замыкание как callback-функцию,
// чтобы удвоить каждый элемент диапазона
$new_numbers = array_map($double, $numbers);

print
implode(' ', $new_numbers);

?>

Результат выполнения приведённого примера:

2 4 6 8 10

Замечание:

Callback-функции, которые зарегистрировали функцией call_user_func() или call_user_func_array(), не вызовутся при непойманном исключении, которое выбросила предыдущая callback-функция.