Ответ
В 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;
}
}
Важные нюансы:
- Область видимости
use: Переменные, включая$this, передаются в замыкание по значению. Если нужно изменять свойство объекта, сам объект передается по ссылке на объект, поэтому изменения свойств через$this->property = ...будут отражаться на исходном объекте. - Статические методы: Для вызова статических методов внутри замыкания используйте
self::methodName()илиstatic::methodName(). Контекст$thisдля статических вызовов не нужен. - Замыкания в статических методах: В статическом методе
$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 в веб-фреймворках.