weakmap 是 php 8 提供的弱引用映射,用于对象元数据缓存以避免内存泄漏;其 key 为弱引用对象,不阻止 gc 回收,value 可任意类型,不支持遍历与序列化。

为什么用 WeakMap 而不是普通数组或 SplObjectStorage
普通数组用对象作键时,会隐式增加引用计数,阻止 GC;SplObjectStorage 同样强持有对象。而 WeakMap 的 key 是弱引用——只要对象没有其他强引用,哪怕它还在 WeakMap 里,也能被回收。这对长期运行的 CLI worker、Swoole 或 ReactPHP 服务特别关键。
基本用法:绑定与读取对象私有数据
WeakMap 实例本身不保存强引用,key 必须是对象(不能是字符串、数字等),value 可以是任意类型:
示例:
$cache = new WeakMap();<br>$user = new User(id: 123);<br>$cache[$user] = ['summary' => 'active', 'last_access' => time()];<br>// 此时 $user 仍可被正常使用<br>var_dump($cache[$user]); // 输出数组<br>unset($user); // 唯一强引用消失<br>// 下次 GC 运行后,$cache[$user] 自动失效,访问返回 null 或触发未定义行为
典型适用场景
-
每对象缓存计算结果:比如对一个用户对象预计算权限树,避免重复调用
getPermissions() - DOM 元素或资源句柄的状态管理:在 Swoole HTTP 服务器中给 Request 对象附加临时上下文
- 享元模式辅助:多个逻辑实例共享同一底层对象,用 WeakMap 存储各自独立的轻量状态
- 监听器注册表:避免因监听器 map 持有事件源对象而导致无法释放
注意事项和限制
- WeakMap 不支持遍历(没有 keys()、values()、foreach 支持),也不能序列化
- 不能用
isset()判断是否存在,只能用array_key_exists()或先 get 再判断是否为 null - GC 清理时机不可控,不适用于需要精确生命周期控制的逻辑
- 不提供 TTL 或淘汰策略,如需过期,需配合时间戳字段手动检查
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











