Как внутри анонимной функции (замыкания) в PHP обратиться к методу или свойству текущего класса?

«Как внутри анонимной функции (замыкания) в PHP обратиться к методу или свойству текущего класса?» — вопрос из категории PHP Core, который задают на 24% собеседований PHP Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

В PHP замыкания, объявленные внутри метода класса, не имеют автоматического доступа к его приватным и защищенным свойствам/методам. Для этого нужно явно передать контекст объекта $this с помощью конструкции use.

Пример: доступ к приватному свойству и методу

class OrderProcessor {
    private $taxRate = 0.20;

    public function calculateTotal(array $items): float {
        // Создаем замыкание для расчета суммы позиции с налогом
        $calculateLineTotal = function ($price, $quantity) use ($this) {
            // Используем $this, переданный через use, для вызова приватного метода
            $subtotal = $price * $quantity;
            return $subtotal + $this->applyTax($subtotal);
        };

        $total = 0;
        foreach ($items as $item) {
            $total += $calculateLineTotal($item['price'], $item['quantity']);
        }
        return $total;
    }

    private function applyTax(float $amount): float {
        return $amount * $this->taxRate;
    }
}

Важные нюансы:

  1. Область видимости use: Переменные, включая $this, передаются в замыкание по значению. Если нужно изменять свойство объекта, сам объект передается по ссылке на объект, поэтому изменения свойств через $this->property = ... будут отражаться на исходном объекте.
  2. Статические методы: Для вызова статических методов внутри замыкания используйте self::methodName() или static::methodName(). Контекст $this для статических вызовов не нужен.
  3. Замыкания в статических методах: В статическом методе $this не определен. Если нужно обратиться к статическому свойству или методу, используйте self::.
class Logger {
    private static $logLevel = 'DEBUG';

    public static function createDebugClosure() {
        // В статическом контексте $this недоступен
        return function ($message) {
            return '[' . self::$logLevel . '] ' . $message; // Обращение к статическому свойству
        };
    }
}

Этот подход часто используется в обработчиках событий, колбэках для array_map/array_filter внутри класса или при создании middleware в веб-фреймворках.