lru缓存需o(1)查找、更新与删除:一、哈希表+spldoublylinkedlist,适合中低频;二、自定义双向链表+映射数组,全操作o(1),适用于高频;三、纯数组模拟,简洁但array_shift()为o(n),仅限低负载。

如果您在PHP中需要构建一个具备自动淘汰机制的缓存系统,而该机制需依据“最近最少使用”原则驱逐旧数据,则必须兼顾O(1)级的查找、更新与删除效率。以下是实现LRU缓存淘汰策略的多种方法:
一、哈希表 + SplDoublyLinkedList 组合方案
利用PHP内置的 SplDoublyLinkedList 模拟双向链表结构,配合关联数组(哈希表)实现键到节点的快速映射。该方案无需手写链表类,适合中低频访问场景;但需注意 offsetUnset() 等操作为O(n),仅适用于非极端性能敏感环境。
1、定义LRUCache类,声明私有属性:容量 $capacity、链表实例 $list、映射数组 $map。
2、在构造函数中初始化 SplDoublyLinkedList,并设置迭代模式为FIFO。
3、get($key) 方法中先检查 $map[$key] 是否存在;若存在,则从链表中移除对应节点并重新插入头部,同时更新映射值。
4、put($key, $value) 方法中,若键已存在则执行更新并前置;若不存在且当前长度已达 $capacity,则调用 pop() 删除尾部节点,并从 $map 中清除对应键。
二、自定义双向链表节点 + 关联数组映射方案
为规避 SplDoublyLinkedList 的O(n)随机访问缺陷,手动实现带 prev 与 next 指针的链表节点类,配合头尾哨兵节点维护顺序。此结构确保所有核心操作均为O(1),适用于高频读写缓存服务。
1、定义 LruNode 类,包含 $key、$value、$prev、$next 四个属性及相应 setter/getter 方法。
2、在 LRUCache 类中维护 $head 与 $tail 哨兵节点,以及 $map 数组用于键到节点的O(1)定位。
3、get($key) 执行时,通过 $map[$key] 获取节点,调用 moveToHead() 将其从原位置解链并插入头部。
4、put($key, $value) 中,若键存在则更新值并前置;若不存在且超容,则调用 removeTail() 删除尾节点,并从 $map 中卸载其键。
三、纯数组模拟LRU(简易轻量方案)
对于缓存规模小、QPS较低且对时间复杂度不敏感的应用,可直接使用PHP关联数组配合 array_shift() 和 unset() 实现逻辑LRU。该方法代码简洁、无额外依赖,但因数组重排导致 array_shift() 为O(n),仅推荐用于开发调试或嵌入式脚本等低负载场景。
1、在构造函数中初始化空数组 $LRUArr 并保存 $capacity。
2、get($key) 中检测键是否存在;若存在,先用 unset() 移除原位置项,再以相同键名追加至数组末尾,实现“访问即置顶”语义。
3、put($key, $value) 中,若键已存在则直接覆盖;若不存在且当前长度等于 $capacity,则遍历数组并用 break 配合 unset() 删除首个元素(即最久未用项)。
4、最后将新键值对赋值给 $LRUArr[$key],完成插入。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











