Передача функции аргументом в PHP (callable, closure, callback)
Передача функции в качестве аргумента в PHP
В PHP функция может быть передана другой функции в качестве аргумента. Это позволяет создавать гибкие и переиспользуемые конструкции, например, функции высшего порядка, сортировки, фильтрации и обработки коллекций. Основной способ - использование типа callable, который может быть строкой с именем функции, массивом с объектом/классом и методом, анонимной функцией или стрелочной функцией.
Самый эффективный и современный вариант - передача анонимной функции (closure) или стрелочной функции, так как они позволяют инкапсулировать логику на месте и захватывать переменные из области видимости.
function applyCallback($value, callable $callback) {
return $callback($value);
}
// Анонимная функция
$result = applyCallback(5, function($x) { return $x * 2; });
echo $result; // 10
// Стрелочная функция (PHP 7.4+)
$result = applyCallback(3, fn($x) => $x + 1);
echo $result; // 4функции работы с массивом php (функции для работы с массивами в php)
В примере applyCallback принимает callable и вызывает его. Тип callable гарантирует, что переданный аргумент может быть вызван как функция. При ошибке (например, передана невызываемая строка) PHP выбросит TypeError. Чтобы избежать ошибок, можно проверять is_callable() перед вызовом.
Как избежать ошибок при передаче неверного типа?
Использовать type hint callable в параметре или проверку через is_callable(). Типичная ошибка - передача строки, не являющейся именем существующей функции. Решение: проверять или использовать try-catch.
Как передать имя существующей функции?
Можно передать строку с именем функции.
function double($x) { return $x * 2; }
$result = applyCallback(4, 'double');
echo $result; // 8функция file php (функция file() в php)
Как передать метод объекта или класса?
Массив из двух элементов: объект/класс и имя метода.
class Math {
public static function square($x) { return $x * $x; }
public function cube($x) { return $x * $x * $x; }
}
// Статический метод
$result = applyCallback(3, ['Math', 'square']);
echo $result; // 9
// Метод объекта
$math = new Math();
$result = applyCallback(2, [$math, 'cube']);
echo $result; // 8функция get php (функция get() в php)
Как использовать замыкания для захвата переменных?
Анонимные функции могут использовать use для доступа к переменным из родительской области.
$multiplier = 3;
$callback = function($x) use ($multiplier) {
return $x * $multiplier;
};
echo applyCallback(5, $callback); // 15функция php выводит данные на экран (вывод данных на экран в php)
Как передать созданную через create_function?
Устаревший способ (PHP 7.2+ deprecated, удалено в 8.0). Не рекомендуется.
// Было: $callback = create_function('$x', 'return $x * 2;');
// Современная замена: анонимная функция.статическая функция php (статические методы в php)
Как передать callable с помощью Closure::fromCallable?
Преобразует любой callable в замыкание.
function triple($x) { return $x * 3; }
$closure = Closure::fromCallable('triple');
echo applyCallback(7, $closure); // 21Php функции даты (функции даты в php)
Удобно, когда нужно сохранить callable как объект-замыкание.
Как передать стрелочную функцию?
Краткая запись анонимной функции, доступна с PHP 7.4.
$result = applyCallback(10, fn($x) => $x ** 2); // 100Расширенные примеры передачи функций в PHP
Использование callable в array_map
$numbers = [1, 2, 3, 4];
$squared = array_map(fn($n) => $n * $n, $numbers);
print_r($squared);Array
(
[0] => 1
[1] => 4
[2] => 9
[3] => 16
)Сортировка пользовательскими критериями (usort)
$people = [
['name' => 'Анна', 'age' => 25],
['name' => 'Борис', 'age' => 20],
['name' => 'Виктор', 'age' => 30]
];
usort($people, function($a, $b) {
return $a['age'] <=> $b['age'];
});
print_r($people);Array
(
[0] => Array ( [name] => Борис [age] => 20 )
[1] => Array ( [name] => Анна [age] => 25 )
[2] => Array ( [name] => Виктор [age] => 30 )
)Фильтрация массива (array_filter) с callback
$numbers = range(1, 10);
$even = array_filter($numbers, fn($v) => $v % 2 == 0);
print_r($even);Array
(
[1] => 2
[3] => 4
[5] => 6
[7] => 8
[9] => 10
)Собственная функция высшего порядка с несколькими аргументами
function applyOperation($a, $b, callable $operation) {
return $operation($a, $b);
}
$sum = applyOperation(5, 3, fn($x, $y) => $x + $y);
$product = applyOperation(4, 2, function($x, $y) { return $x * $y; });
echo "Сумма: $sum, Произведение: $product"; // Сумма: 8, Произведение: 8Композиция функций с помощью array_reduce
$functions = [
fn($x) => $x + 1,
fn($x) => $x * 2,
fn($x) => $x - 3
];
$composed = array_reduce($functions, function($carry, $fn) {
return fn($x) => $fn($carry($x));
}, fn($x) => $x);
echo $composed(5); // ((5+1)*2)-3 = 9Обработка ошибок при передаче callable
function safeApply($value, $callback) {
if (!is_callable($callback)) {
throw new InvalidArgumentException("Callback не является вызываемой структурой");
}
return $callback($value);
}
try {
echo safeApply(10, 'nonexistent_function');
} catch (InvalidArgumentException $e) {
echo $e->getMessage();
} // Вывод: Callback не является вызываемой структуройПередача callable как аргумента в метод объекта
class Logger {
public function log($message, callable $formatter = null) {
$formatted = $formatter ? $formatter($message) : $message;
echo $formatted;
}
}
$logger = new Logger();
$logger->log('Ошибка', fn($m) => "[ERROR] " . strtoupper($m)); // [ERROR] ОШИБКАДинамическое создание callback для многократного использования
function multiplier($factor) {
return fn($x) => $x * $factor;
}
$double = multiplier(2);
$triple = multiplier(3);
echo $double(5) . " " . $triple(5); // 10 15Эти примеры показывают гибкость передачи функций в PHP. Использование callable позволяет строить чистый, модульный код с возможностью повторного использования логики.