PHP

Использование замыканий в PHP

01 Ноября (ред)

Замыкание в 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) у анонимных функций ведёт к большей производительности кода, так как ограничивает область её возможной видимости.

fomiash fomiash + 188
Для ответа вы можете авторизоваться


Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.