← Назад к вопросам

Что замыкается в замыкании в PHP?

2.0 Middle🔥 121 комментариев
#PHP Core

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI7 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Что такое замыкание в PHP?

В PHP замыкание (closure) — это анонимная функция, которая может "захватывать" (замыкать) переменные из внешней области видимости, даже после того, как эта область видимости прекратила своё существование. Это позволяет функции сохранять состояние между вызовами и получать доступ к контексту, в котором она была определена.

Что именно "замыкается"?

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

Пример захвата переменной:

$message = "Привет";

$closure = function($name) use ($message) {
    return $message . ", " . $name . "!";
};

echo $closure("Мир"); // Вывод: Привет, Мир!

В этом примере переменная $message захватывается из внешней области видимости с помощью конструкции use.

Особенности замыканий в PHP

1. Захват по значению vs по ссылке

По умолчанию переменные захватываются по значению. Это означает, что замыкание получает копию значения переменной на момент создания:

$count = 0;
$closure = function() use ($count) {
    return ++$count;
};

echo $closure(); // 1
echo $closure(); // 1 (всегда 1, т.к. работаем с копией)
echo $count;     // 0 (оригинальная переменная не изменилась)

Для захвата по ссылке нужно использовать амперсанд:

$count = 0;
$closure = function() use (&$count) {
    return ++$count;
};

echo $closure(); // 1
echo $closure(); // 2
echo $count;     // 2 (оригинальная переменная изменилась)

2. Захват объекта всегда происходит по ссылке

Когда захватывается объект, PHP автоматически использует передачу по ссылке:

class Counter {
    public $value = 0;
}

$counter = new Counter();
$closure = function() use ($counter) {
    $counter->value++;
};

$closure();
$closure();
echo $counter->value; // 2

3. $this в контексте классов

В методах класса анонимные функции автоматически получают доступ к $this и приватным членам класса, если они определены в контексте класса:

class Example {
    private $secret = "секретные данные";
    
    public function getClosure() {
        return function() {
            return $this->secret; // Имеем доступ к приватному свойству
        };
    }
}

$example = new Example();
$closure = $example->getClosure();
echo $closure(); // вывод: секретные данные

Практическое применение замыканий

1. Коллбэки и обработчики событий

$users = ["Алексей", "Мария", "Иван"];
usort($users, function($a, $b) {
    return strcmp($a, $b);
});

2. Создание функций-фабрик

function createMultiplier($factor) {
    return function($number) use ($factor) {
        return $number * $factor;
    };
}

$double = createMultiplier(2);
$triple = createMultiplier(3);

echo $double(5); // 10
echo $triple(5); // 15

3. Инкапсуляция состояния

function createCounter($start = 0) {
    $count = $start;
    
    return [
        'increment' => function() use (&$count) {
            return ++$count;
        },
        'decrement' => function() use (&$count) {
            return --$count;
        },
        'get' => function() use (&$count) {
            return $count;
        }
    ];
}

$counter = createCounter(5);
echo $counter['increment'](); // 6
echo $counter['decrement'](); // 5

Важные технические детали

  1. Замыкания реализованы как объекты класса Closure — это внутренний класс PHP, что отличает их от обычных функций.

  2. Замыкания могут быть вызваны как функции благодаря реализации магического метода __invoke().

  3. Метод bindTo() и bind() позволяют изменять контекст выполнения замыкания:

$closure = function() {
    return $this->property;
};

class MyClass {
    public $property = "Значение";
}

$obj = new MyClass();
$boundClosure = $closure->bindTo($obj, $obj);
echo $boundClosure(); // Вывод: Значение

Заключение

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

Что замыкается в замыкании в PHP? | PrepBro