Какой контекст (область видимости) доступен анонимной функции, определенной внутри метода класса в PHP?

Ответ

Область видимости анонимной функции зависит от способа ее определения:

1. Обычная анонимная функция (с function() use (...)):

  • Не имеет доступа к переменным родительской области (метода) и к $this по умолчанию.
  • Доступ нужно явно указать через конструкцию use.
  • Начиная с PHP 7.1, для захвата $this его также нужно явно указать в use, иначе будет фатальная ошибка.
class MyClass {
    private $prop = 'private';
    public function method() {
        $localVar = 'local';
        // Явный захват переменных и $this
        $func = function() use ($localVar, $this) {
            echo $localVar; // 'local'
            echo $this->prop; // 'private' (доступ к private свойству!)
        };
        $func();
    }
}

2. Стрелочная функция (PHP 7.4+):

  • Автоматически захватывает переменные из родительской области видимости по значению.
  • Если определена в нестатическом методе, автоматически захватывает $this.
  • Более лаконичный синтаксис.
class MyClass {
    private $prop = 'private';
    public function method() {
        $localVar = 'local';
        // Автоматический захват $localVar и $this
        $arrowFunc = fn() => $localVar . ' ' . $this->prop;
        echo $arrowFunc(); // 'local private'
    }
}

Важное отличие: В статическом методе $this не определен, поэтому его нельзя захватить ни одним из способов. Стрелочные функции, определенные в статическом контексте, также не будут иметь доступа к $this.

Ответ 18+ 🔞

Ну ты представляешь, эта ваша область видимости в анонимках — просто ёперный театр какой-то! Сидишь такой, пишешь код, думаешь — ну функция же внутри метода, значит, всё видит. А нихуя подобного! Тут как в том анекдоте про тещу в холодильнике — доступ нужно оформлять отдельно.

Вот смотри, классическая анонимка через function() use (...). Без этого самого use она нихуя не видит, как будто в соседней квартире сидит. Ни локальных переменных родительского метода, ни священного $this. Полный штиль, чувак. И внимание, с PHP 7.1 — если ты $this в use не пропишешь, тебе сразу фатальная ошибка в морду, типа «а пошёл ты на хуй, я не буду догадываться». Вот пример, чтобы не быть голословным:

class MyClass {
    private $prop = 'private';
    public function method() {
        $localVar = 'local';
        // Явный захват переменных и $this
        $func = function() use ($localVar, $this) {
            echo $localVar; // 'local'
            echo $this->prop; // 'private' (доступ к private свойству!)
        };
        $func();
    }
}

Видишь? Всё явно, как в аптеке. Взял $localVar и $this, запихнул в use — и только тогда внутри функции они становятся своими в доску. И да, через $this она может даже приватные свойства читать — вот это доверия ебать ноль к инкапсуляции, но так работает.

А теперь, блядь, смотри сюда — стрелочные функции, которые с PHP 7.4 подъехали. Это вообще другая история, ядрёна вошь! Они умные, как мартышлюшки. Им ничего явно указывать не надо. Они автоматом, по-тихому, сцуко, захватывают все переменные из внешней области, которые внутри тела упоминаются. И $this тоже, если метод нестатический. Красота же!

class MyClass {
    private $prop = 'private';
    public function method() {
        $localVar = 'local';
        // Автоматический захват $localVar и $this
        $arrowFunc = fn() => $localVar . ' ' . $this->prop;
        echo $arrowFunc(); // 'local private'
    }
}

Короче, синтаксис — просто песня, одна строка. Никаких этих use, никакой волокиты. Но запомни, чувак, главный подвох: если ты в статическом методе, то там $this вообще не существует, он — хуй с горы. И стрелочная функция, какой бы хитрой жопой она ни была, его оттуда не достанет, потому что его нет в принципе. Так что не пытайся, бесполезно.

Вот и вся магия. Обычная анонимка — строгая, требует явного разрешения на всё. Стрелочная — шустрая, сама всё стырит, что нужно. Выбирай, что для твоего случая больше подходит, и не охуей, когда что-то не работает.