WeakMap 是一种将对象作为键来访问的映射结构,与其他类似的数据结构(如 SplObjectStorage)不同的是,WeakMap 中的对象键不会增加对象的引用计数。如果对象的唯一剩余引用是作为 WeakMap 键的引用,那么该对象将被垃圾收集并从 WeakMap 中移除。
一、用途
WeakMap 的主要用途是为对象编译数据派生缓存,因为它们可以保证只要对象没有其他强引用,缓存中的数据就会随之自动失效。
WeakMap 实现了 ArrayAccess、 Iterator、Countable, 因此大多数情况下,它能和关联数组一样使用。
1、作为实现了 ArrayAccess 接口的类,WeakMap 可以使用数组索引来访问和修改其中的元素,例如:
$map = new WeakMap(); $obj1 = new stdClass(); $obj2 = new stdClass(); // 使用数组索引添加元素 $map[$obj1] = 'value 1'; $map[$obj2] = 'value 2'; // 使用数组索引获取元素 echo $map[$obj1]; // 输出:value 1 // 使用数组索引删除元素 unset($map[$obj1]);
2、作为实现了 Iterator 接口的类,WeakMap 可以使用 foreach 循环遍历其中的元素,例如:
$map = new WeakMap(); $obj1 = new stdClass(); $obj2 = new stdClass(); $map[$obj1] = 'value 1'; $map[$obj2] = 'value 2'; // 使用 foreach 遍历元素 foreach ($map as $key => $value) { echo "$key => $value\n"; }
3、作为实现了 Countable 接口的类,WeakMap 可以使用 count() 函数获取其中元素的数量,例如:
$map = new WeakMap(); $obj1 = new stdClass(); $obj2 = new stdClass(); $map[$obj1] = 'value 1'; $map[$obj2] = 'value 2'; // 使用 count 函数获取元素数量 echo count($map); // 输出:2
二、类摘要
final class WeakMap implements ArrayAccess, Countable, IteratorAggregate { /* 方法 */ public count(): int public getIterator(): Iterator public offsetExists(object $object): bool public offsetGet(object $object): mixed public offsetSet(object $object, mixed $value): void public offsetUnset(object $object): void }
三、示例
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)
四、常用方法
以下是 SplObjectStorage 类常用的一些方法:
- attach($object, $data = null):将对象添加到集合中,并可以关联一个可选的数据。
- detach($object):从集合中移除指定的对象。
- contains($object):检查集合中是否包含指定的对象。
- offsetGet($object):返回与指定对象关联的数据。
- offsetSet($object, $data):为指定的对象设置关联的数据。
- offsetUnset($object):从集合中移除指定的对象。
- count():返回集合中的对象数量。