当前位置:首页 > PHP

php 实现lru

2026-02-14 19:53:27PHP

LRU 缓存实现原理

LRU(Least Recently Used)是一种缓存淘汰策略,当缓存空间不足时,优先移除最久未被使用的数据。PHP 实现 LRU 通常需要结合哈希表(快速查找)和双向链表(维护访问顺序)。

基于数组和链表的实现

PHP 中可以通过数组模拟哈希表,结合 SplDoublyLinkedList 实现 LRU:

class LRUCache {
    private $capacity;
    private $map = [];
    private $list;

    public function __construct($capacity) {
        $this->capacity = $capacity;
        $this->list = new SplDoublyLinkedList();
    }

    public function get($key) {
        if (!isset($this->map[$key])) {
            return -1;
        }

        $node = $this->map[$key];
        $this->list->push($this->list->shift()); // 移动到链表尾部
        return $node['value'];
    }

    public function put($key, $value) {
        if (isset($this->map[$key])) {
            unset($this->map[$key]);
            $this->list->shift(); // 移除旧节点
        }

        if (count($this->map) >= $this->capacity) {
            $oldKey = $this->list->shift();
            unset($this->map[$oldKey]);
        }

        $this->list->push(['key' => $key, 'value' => $value]);
        $this->map[$key] = end($this->list);
    }
}

使用 SplDoublyLinkedList 优化

SplDoublyLinkedList 提供高效的头尾操作,适合 LRU 场景:

class LRUCache {
    private $capacity;
    private $map = [];
    private $list;

    public function __construct($capacity) {
        $this->capacity = $capacity;
        $this->list = new SplDoublyLinkedList();
        $this->list->setIteratorMode(SplDoublyLinkedList::IT_MODE_FIFO);
    }

    public function get($key) {
        if (!isset($this->map[$key])) {
            return -1;
        }

        $node = $this->map[$key];
        $this->list->push($node);
        $this->list->offsetUnset($this->list->key());
        return $node['value'];
    }

    public function put($key, $value) {
        if (isset($this->map[$key])) {
            $this->list->offsetUnset($this->list->key());
        }

        if (count($this->map) >= $this->capacity) {
            $oldNode = $this->list->shift();
            unset($this->map[$oldNode['key']]);
        }

        $node = ['key' => $key, 'value' => $value];
        $this->list->push($node);
        $this->map[$key] = $node;
    }
}

纯数组实现方案

如果环境限制不能使用 SPL,可以用纯数组模拟:

php 实现lru

class LRUCache {
    private $capacity;
    private $cache = [];
    private $order = [];

    public function __construct($capacity) {
        $this->capacity = $capacity;
    }

    public function get($key) {
        if (!isset($this->cache[$key])) {
            return -1;
        }

        unset($this->order[array_search($key, $this->order)]);
        $this->order[] = $key;
        return $this->cache[$key];
    }

    public function put($key, $value) {
        if (isset($this->cache[$key])) {
            unset($this->order[array_search($key, $this->order)]);
        }

        if (count($this->cache) >= $this->capacity) {
            $oldKey = array_shift($this->order);
            unset($this->cache[$oldKey]);
        }

        $this->cache[$key] = $value;
        $this->order[] = $key;
    }
}

时间复杂度分析

  • 哈希表操作:O(1) 时间完成键值查找
  • 链表操作:移动节点到尾部或删除头部节点均为 O(1)
  • 数组实现array_search 导致 O(n) 时间复杂度,适合小规模数据

实际应用建议

  • 生产环境推荐使用 SplDoublyLinkedList 方案,性能最佳
  • 超大规模数据建议使用 Redis 等专业缓存系统内置的 LRU 策略
  • 缓存容量需要根据业务场景合理设置,过小会导致频繁淘汰,过大浪费内存

标签: phplru
分享给朋友:

相关文章

php实现文件上传

php实现文件上传

文件上传的基本实现 在PHP中实现文件上传需要使用$_FILES超全局数组处理上传的文件数据。表单必须设置enctype="multipart/form-data"属性,并采用POST方法提交。 创…

php实现搜索功能

php实现搜索功能

实现基本的搜索功能 在PHP中实现搜索功能通常涉及数据库查询。以下是一个简单的实现方式,假设使用MySQL数据库: <?php // 连接数据库 $conn = new mysqli('loc…

php实现队列

php实现队列

PHP实现队列的方法 队列是一种先进先出(FIFO)的数据结构,PHP可以通过多种方式实现队列功能。 使用数组模拟队列 PHP数组可以模拟队列的基本操作,通过array_push和array_shi…

php实现mysql

php实现mysql

PHP 连接 MySQL 的基本方法 PHP 提供了多种方式与 MySQL 数据库进行交互,以下是最常用的几种方法。 使用 MySQLi 扩展 MySQLi 是 MySQL 的改进扩展,支持面向对…

php 实现文件下载

php 实现文件下载

实现文件下载的基本方法 使用 PHP 实现文件下载的核心是通过设置 HTTP 头部信息,强制浏览器将文件作为附件下载而非直接显示。以下是一个基础实现示例: $file_path = '/path/t…

php 实现队列

php 实现队列

PHP 实现队列的方法 PHP 可以通过多种方式实现队列功能,以下是几种常见的实现方法: 使用数组实现队列 PHP 数组可以通过 array_push 和 array_shift 函数模拟队列的先进…