Примеры использования лямбда-выражений в PHP

Раздел: PHP -> Анонимные и стрелочные функции

Анонимные функции в PHP: основы и варианты использования

Анонимная функция (также называемая лямбдой) представляет собой функцию без имени. Она может быть сохранена в переменную, передана в качестве аргумента другой функции или возвращена из функции. Это мощный инструмент для создания гибкого кода, особенно при работе с массивами и функциями высшего порядка.

Основной способ создания

Анонимную функцию создают с помощью ключевого слова function и присваивают переменной.

$square = function($x) {
    return $x * $x;
};
echo $square(5); // 25

анонимная функция php (анонимные функции в php)

После закрывающей фигурной скобки обязательно ставится точка с запятой. Вызов происходит как у обычной функции.

Типичные ошибки:

Пропущенная точка с запятой после определения вызывает синтаксическую ошибку PHP.

Попытка вызвать анонимную функцию до её присвоения переменной приведет к ошибке undefined function.

Как применить анонимную функцию ко всем элементам массива?

Функция array_map принимает callback и массив, возвращая новый массив.

$numbers = [1, 2, 3, 4];
$squared = array_map(function($n) {
    return $n * $n;
}, $numbers);
print_r($squared); // [1, 4, 9, 16]

стрелочные функции php (стрелочные функции в php)

Callback выполняется для каждого элемента, результат собирается в новый массив. Исходный массив не изменяется.

Если внутри callback требуется обратиться к внешней переменной, необходимо использовать use, иначе переменная будет не определена.

Как использовать внешние переменные внутри анонимной функции?

Конструкция use позволяет захватить переменные из родительской области видимости.

$factor = 3;
$multiply = function($x) use ($factor) {
    return $x * $factor;
};
echo $multiply(4); // 12

Переменная $factor копируется в замыкание. Чтобы изменить внешнюю переменную, используйте ссылку: use (&$factor).

Если переменная, переданная в use, не существует на момент объявления, PHP выдаст предупреждение. Также следует помнить, что изменения переменной внутри замыкания не влияют на оригинал, если не передана ссылка.

Как создать фабрику функций с помощью замыкания?

Функция может возвращать анонимную функцию, которая сохраняет своё окружение.

function createGreeter($greeting) {
    return function($name) use ($greeting) {
        return $greeting . ', ' . $name . '!';
    };
}
$helloGreeter = createGreeter('Hello');
echo $helloGreeter('World'); // Hello, World!

Каждый вызов createGreeter создаёт новую анонимную функцию с собственным значением $greeting.

Значение захваченной переменной фиксируется в момент создания замыкания. Для изменения захваченной переменной внутри возвращаемой функции нужно передавать её по ссылке.

Как сделать анонимную функцию рекурсивной?

Для рекурсии необходимо передать ссылку на саму функцию через use (&$func).

$factorial = function($n) use (&$factorial) {
    if ($n <= 1) return 1;
    return $n * $factorial($n - 1);
};
echo $factorial(5); // 120

Без ссылки $factorial внутри функции не определена.

Если забыть амперсанд, будет бесконечный цикл или ошибка, так как $factorial внутри будет null.

Чем отличаются стрелочные функции от обычных анонимных?

Стрелочные функции (fn) имеют лаконичный синтаксис и автоматически захватывают переменные по значению.

$factor = 2;
$multiply = fn($x) => $x * $factor;
echo $multiply(5); // 10

Не требуется use. Тело может содержать только одно выражение, результат которого автоматически возвращается.

Стрелочные функции не подходят для многострочной логики или инструкций вроде return, echo и т.д. Для сложных сценариев используйте обычные анонимные функции.

Расширенные примеры анонимных функций в PHP

Ниже приведены более сложные сценарии использования анонимных функций.

Пример 1: Сумма квадратов нечетных чисел с array_reduce

Пример
$numbers = [1, 2, 3, 4, 5, 6];
$sumOddSquares = array_reduce($numbers, function($carry, $item) {
    if ($item % 2 != 0) {
        $carry += $item * $item;
    }
    return $carry;
}, 0);
echo $sumOddSquares; // 1+9+25 = 35
35

Пример 2: Динамический фильтр по диапазону

Пример
function createRangeFilter($min, $max) {
    return function($value) use ($min, $max) {
        return $value >= $min && $value <= $max;
    };
}
$filter = createRangeFilter(10, 20);
$values = [5, 15, 25, 10, 20, 30];
$filtered = array_filter($values, $filter);
print_r(array_values($filtered)); // [15, 10, 20]
Array ( [0] => 15 [1] => 10 [2] => 20 )

Пример 3: Мемоизация (кэширование) с помощью замыкания

Пример
function memoize($func) {
    $cache = [];
    return function($arg) use ($func, &$cache) {
        if (!array_key_exists($arg, $cache)) {
            $cache[$arg] = $func($arg);
        }
        return $cache[$arg];
    };
}
$factorial = memoize(function($n) use (&$factorial) {
    if ($n <= 1) return 1;
    return $n * $factorial($n - 1);
});
echo $factorial(10); // 3628800
echo $factorial(10); // из кэша (результат тот же)
3628800

Пример 4: Композиция функций

Пример
$addOne = fn($x) => $x + 1;
$multiplyTwo = fn($x) => $x * 2;
$compose = function($f, $g) {
    return function($x) use ($f, $g) {
        return $g($f($x));
    };
};
$addOneThenMultiplyTwo = $compose($addOne, $multiplyTwo);
echo $addOneThenMultiplyTwo(5); // (5+1)*2 = 12
12

Пример 5: Инициализация статического свойства класса

Пример
class Config {
    public static $data = [];
}
Config::$data = (function() {
    return ['db' => 'mysql', 'host' => 'localhost'];
})();
print_r(Config::$data);
Array ( [db] => mysql [host] => localhost )

Пример 6: Изменение внешней переменной по ссылке

Пример
$counter = 0;
$increment = function() use (&$counter) {
    $counter++;
};
$increment();
$increment();
echo $counter; // 2
2

Пример 7: Сортировка с несколькими условиями через usort

Пример
$data = [
    ['name' => 'Alice', 'age' => 30],
    ['name' => 'Bob', 'age' => 25],
    ['name' => 'Charlie', 'age' => 30],
];
usort($data, function($a, $b) {
    if ($a['age'] != $b['age']) {
        return $a['age'] - $b['age'];
    }
    return strcmp($a['name'], $b['name']);
});
print_r($data);
Array ( [0] => Array ( [name] => Bob [age] => 25 ) [1] => Array ( [name] => Alice [age] => 30 ) [2] => Array ( [name] => Charlie [age] => 30 ) )

Анонимные функции в PHP - comments

En
анонимная функция php (php)