Замыкание в PHP - это способность анонимной функции взаимодействовать с её окружением. То есть переменные из контекста замыкания могут быть использованы внутри функции.
Анонимная функция - это обычная функция не имеющая названия. Может быть присвоена переменной и не только, также может быть возвращаемым результатом функции или метода, аналогично экземпляру внутреннего класса Closure, которым представлена.
Пример обычной анонимной функции (без замыкания):
// Присвоение анонимной функции в переменную.
$showNumber = function() {
echo 72;
};
// Переменную можно теперь использовать как функцию.
$showNumber(); // 72
При использовании добавочного выражения use() к анонимной функции - она становится замыканием и возникает возможность через это выражение открывать видимость переменных окружения в функции при объявлении. Пример:
// Переменные окружения.
$x = 10;
$y = 4;
// Переменные $x и $y видимы внутри функции.
$showArea = function() use ($x, $y) {
echo $x * $y ;
};
$showArea(); // 40
При этом анонимная функция в этих случаях может через аргументы получать значения как обычная функция:
// Пример замыкания с аргументом.
$x = 10;
$y = 4;
$showVolume = function(int $z) use ($x, $y) {
echo $x * $y * $z ;
};
$showVolume(2); // 80
$showVolume(10); // 400
В PHP также существует тип анонимных функций с короткой записью, так называемые стрелочные функции или короткие замыкания. Вместо того чтобы определять функции такого типа с помощью ключевого слова function и заключать тело в фигурные скобки, как в случае с замыканием, стрелочные функции используют ключевое слово fn и одно выражение. Также важно отметить, что стрелочные функции должны возвращать значение. Поэтому их нельзя использовать для функций, которые не возвращают значения, в отличие от замыканий. Примеры:
// Пример стрелочной функции (замыкания).
$x = 10;
$y = 4;
// Переменные окружения можно использовать в функции.
$showArea = fn() => $x * $y;
echo $showArea(); // 40
// Пример стрелочной функции (замыкания) с аргументом.
$x = 10;
$y = 4;
$showVolume = fn(int $z)=>$x * $y * $z;
echo $showVolume(2); // 80
echo $showVolume(10); // 400
Более сложный пример для понимания как замыкание работает с переменными окружения:
class Env
{
public static $x = 10;
public static $y = 4;
public function volume(): \Closure
{
return fn(int $z) => self::$x * self::$y * $z;
}
}
// Присваивание переменной возвращаемого методом volume замыкания.
$showVolume = (new Env())->volume();
echo $showVolume(10); // 400
// Изменение переменной окружения для замыкания.
Env::$x = 20;
echo $showVolume(10); // 800
Как видно из примера возвращаемый тип метода volume указан как Closure. Это особый тип для интерпретации PHP анонимных функций (и замыканий) в качестве экземпляра внутреннего класса Closure.
Существуют также статические анонимные функции которые запрещают связывать их с текущим классом при помощи ключевого слова static перед функцией. Например, вот такое использование вызовет ошибку:
class Env
{
function __construct()
{
$fn = static function() {
// Обращение к $this, что не позволяет сделать ключевое слово static.
var_dump($this);
};
$fn();
}
};
new Env();
Считается, что ограничение до статической (добавление static) у анонимных функций ведёт к большей производительности кода, так как ограничивает область её возможной видимости.
