CakeFest 2024: The Official CakePHP Conference

Класс WeakMap

(PHP 8)

Введение

Класс WeakMap — карта, или словарь, который принимает объекты как ключи. Однако, объект в ключе экземпляра WeakMap не влияет на счётчик ссылок объекта, в отличие от аналогичного в остальном класса SplObjectStorage. То есть, как только единственной оставшейся ссылкой на объект будет ключ экземпляра WeakMap, сборщик мусора соберёт и удалит объект из экземпляра WeakMap. Основная задача класса — создавать кеши данных, которые получили из объекта, которым не нужно жить дольше, чем объект.

Класс WeakMap реализует интерфейсы ArrayAccess, Traversable (через интерфейс IteratorAggregate) и Countable, поэтому с объектом класса часто работают так же, как с ассоциативным массивом.

Обзор классов

final class WeakMap implements ArrayAccess, Countable, IteratorAggregate {
/* Методы */
public count(): int
public offsetExists(object $object): bool
public offsetGet(object $object): mixed
public offsetSet(object $object, mixed $value): void
public offsetUnset(object $object): void
}

Примеры

Пример #1 Пример использования класса Weakmap

<?php

$wm
= new WeakMap();

$o = new stdClass;

class
A {
public function
__destruct() {
echo
"Уничтожено!\n";
}
}

$wm[$o] = new A;

var_dump(count($wm));
echo
"Сброс...\n";
unset(
$o);
echo
"Готово\n";
var_dump(count($wm));

?>

Результат выполнения приведённого примера:

int(1)
Сброс...
Уничтожено!
Готово
int(0)

Содержание

  • WeakMap::count — Подсчитывает количество живых записей в коллекции (map)
  • WeakMap::getIterator — Получает внешний итератор
  • WeakMap::offsetExists — Проверяет, есть ли в коллекции (map) определённый объект
  • WeakMap::offsetGet — Возвращает значение, на которое указывает определённый объект
  • WeakMap::offsetSet — Обновляет коллекцию (map) новой парой ключ-значение
  • WeakMap::offsetUnset — Удаляет запись из коллекции (map)
add a note

User Contributed Notes 1 note

up
2
Samu
4 months ago
PHP's implementation of WeakMap allows for iterating over the contents of the weak map, hence it's important to understand why it is sometimes dangerous and requires careful thought.

If the objects of the WeakMap are "managed" by other services such as Doctrine's EntityManager, it is never safe to assume that if the object still exists in the weak map, it is still managed by Doctrine and therefore safe to consume.

Doctrine might have already thrown that entity away but some unrelated piece of code might still hold a reference to it, hence it still existing in the map as well.

If you are placing managed objects into the WeakMap and later iterating over the WeakMap (e.g. after Doctrine flush), then for each such object you must verify that it is still valid in the context of the source of the object.

For example assigning a detached Doctrine entity to another entity's property would result in errors about non-persisted / non-managed entities being found in the hierarchy.
To Top