WeakMap クラス
(PHP 8)
はじめに
WeakMap は、 オブジェクトをキーとして受け入れるマップ(辞書)です。 SplObjectStorage と似ていますが、 WeakMap のキーとなるオブジェクトは、 オブジェクトのリファレンスカウントが更新されません。 つまり、WeakMap のキーとなっているオブジェクトだけが唯一の残された参照だった場合、 オブジェクトはガベージコレクションの対象となり WeakMap から削除されます。 WeakMap の用途は、 長く生き残る必要がないオブジェクトから派生した、 データのキャッシュを作ることです。
WeakMap は ArrayAccess, Traversable (IteratorAggregate 経由), Countable を実装しています。 よって、ほとんどのケースで、 連想配列と同じやり方で操作できます。
クラス概要
/* メソッド */
}例
例1 Weakmap の使い方の例
<?php
$wm = new WeakMap();
$o = new stdClass;
class A {
public function __destruct() {
echo "Dead!\n";
}
}
$wm[$o] = new A;
var_dump(count($wm));
echo "Unsetting...\n";
unset($o);
echo "Done\n";
var_dump(count($wm));
上の例の出力は以下となります。
int(1) Unsetting... Dead! Done int(0)
目次
- WeakMap::count — マップ内に存在する有効なエントリの数を数える
- WeakMap::getIterator — イテレータを取得する
- WeakMap::offsetExists — あるオブジェクトがマップ内に存在するかを調べる
- WeakMap::offsetGet — オブジェクトが指す値を返す
- WeakMap::offsetSet — 新しいキーと値でマップを更新する
- WeakMap::offsetUnset — マップからエントリを削除する
+add a note
User Contributed Notes 2 notes
Samu ¶
1 year 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.
Anton ¶
8 months ago
Keep in mind that if Enum case is put as a key to WeakMap, it will never be removed because it will always have unless 1 reference to it under the hood (not sure why, probably because enum is basically a constant).
Therefore, both WeakMaps below will always have key Enum::Case. However, you still are able to unset it manually:
$weakMap = new WeakMap();
$object = Enum::Case;
$weakMap[$object] = 123;
unset($object);
var_dump($weakMap->count()); // 1
///
$weakMap = new WeakMap();
$weakMap[Enum::Case] = 123;
var_dump($weakMap->count()); // 1
///
$weakMap = new WeakMap();
$weakMap[Enum::Case] = 123;
unset($weakMap[Enum::Case]);
var_dump($weakMap->count()); // 0
↑ and ↓ to navigate •
Enter to select •
Esc to close
Press Enter without
selection to search using Google