Замикання, створене всередині методу класу, автоматично захоплює $this - навіть якщо не використовує його. Ключове слово static вимикає це:
final class ReportBuilder
{
public function totals(array $rows): array
{
return array_map(static fn (array $row): int => $row['qty'] * $row['price'], $rows);
}
}
Навіщо:
- Пам'ять і час життя об'єкта. Звичайне замикання тримає посилання на
$this. Якщо його зберегли надовго (у кеші, в реєстрі обробників подій, у властивості іншого об'єкта), то й весь об'єкт з усіма залежностями не звільниться. У довгоживучих процесах (Octane, воркери) це шлях до витоків пам'яті. - Ясність намірів.
staticпоказує читачу й аналізатору: колбек не залежить від стану об'єкта, це чиста функція даних. - Захист від випадкового доступу: використання
$thisу статичному замиканні - помилка, а не тиха залежність. - Незначна економія: менше роботи на прив'язку контексту.
Обмеження: статичне замикання не можна прив'язати до об'єкта через bind()/bindTo(). Тому в місцях, де фреймворк навмисно прив'язує замикання (макроси Laravel, деякі колбеки конфігурації), static ламає поведінку.
Практика: багато команд вмикають правило PHP-CS-Fixer static_lambda, яке автоматично додає static до замикань, що не використовують $this. Rector має аналогічне правило.
Те саме для стрілкових функцій: static fn - стрілкова функція без прив'язки $this, але з автоматичним захопленням інших зовнішніх змінних.