Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Навіщо WeakMap і WeakReference у PHP?

PHP звільняє об'єкт, коли на нього не лишається посилань. Звичайний кеш, що тримає об'єкти як ключі чи значення, не дає їх звільнити - навіть коли решта програми про них уже забула. У довгоживучих процесах (воркери, Octane) це витік пам'яті.

WeakReference (PHP 7.4) - посилання, яке не заважає збирачу сміття:

$user = new User();
$ref = WeakReference::create($user);

$ref->get();   // об'єкт
unset($user);
$ref->get();   // null - об'єкт уже звільнено

WeakMap (PHP 8.0) - словник, де ключі - об'єкти, утримувані слабко. Коли ключ-об'єкт звільнено, запис зникає з мапи сам:

final class PriceCalculator
{
    private WeakMap $cache;

    public function __construct()
    {
        $this->cache = new WeakMap();
    }

    public function totalFor(Order $order): int
    {
        return $this->cache[$order] ??= $this->expensiveCalculation($order);
    }
}

Кеш живе рівно стільки, скільки живе кожне замовлення, і не росте безмежно.

Де застосовують:

  • Мемоізація за об'єктом-аргументом - як у прикладі.
  • Метадані до чужих об'єктів, які не можна змінити (сутності ORM, об'єкти бібліотек).
  • Реєстри й ідентичні мапи в ORM і контейнерах, що не мають утримувати сутності довше за запит.

Обмеження: ключі WeakMap - лише об'єкти; значення утримуються сильно (якщо значення посилається на ключ, запис не звільниться). Момент звільнення залежить від лічильника посилань і збирача циклів, тож логіку коректності на ньому не будують - лише оптимізації.

Докладніше в документації: WeakMap

Перевір себе

20 випадкових питань за спробу, після завершення - розбір кожної помилки

Схожі питання