Анонимные функции и замыкания
Функцию можно положить в переменную, передать в другую функцию или вернуть из неё. Такие функции не имеют имени и называются анонимными. Вы уже встречали их в array_map() и usort().
Функция в переменной
Анонимную функцию объявляют без имени и заканчивают точкой с запятой:
<?php
$double = function ($number) {
return $number * 2;
};
echo $double(5); // 10Вызывают её через переменную — с тем же знаком $.
Функция как аргумент
Главное применение — передать поведение в другую функцию:
<?php
$words = ['php', 'html', 'css'];
$upper = array_map(function ($word) {
return strtoupper($word);
}, $words);
echo implode(', ', $upper); // PHP, HTML, CSSЗамыкание и use
Обычная анонимная функция не видит переменных снаружи. Нужные перечисляют в use — функция «захватывает» их значения:
<?php
$tax = 0.2;
$withTax = function ($price) use ($tax) {
return $price * (1 + $tax);
};
echo $withTax(100); // 120Функцию с захваченными переменными называют замыканием. Значение копируется в момент создания: если позже изменить $tax, функция этого не заметит.
Стрелочные функции
Короткая запись fn подходит для функций из одного выражения. Внешние переменные она видит сама, use не нужен:
<?php
$tax = 0.2;
$withTax = fn ($price) => $price * (1 + $tax);
echo $withTax(100); // 120Слово return не пишут: результат выражения возвращается автоматически.
Функция, которая возвращает функцию
Так создают семейство похожих функций, не повторяя код:
<?php
function multiplier($factor)
{
return fn ($number) => $number * $factor;
}
$double = multiplier(2);
$triple = multiplier(3);
echo $double(10), ' ', $triple(10); // 20 30Каждая возвращённая функция помнит своё значение $factor.
Тип callable
Параметр, в который ожидают функцию, отмечают типом callable:
<?php
function applyTwice(callable $action, $value)
{
return $action($action($value));
}
echo applyTwice(fn ($n) => $n + 3, 10), "\n"; // 16
echo applyTwice('strrev', 'abc'); // abcИмя встроенной функции можно передать строкой.
Частая ошибка
Стрелочная функция получает копии внешних переменных и изменить их не может. Чтобы менять переменную снаружи, нужна обычная анонимная функция и знак & в use:
<?php
$count = 0;
$increment = function () use (&$count) {
$count++;
};
$increment();
$increment();
echo $count; // 2