LRU Cache in Pure PHP Using Ordered Arrays
Exploits PHP array insertion order: get() unsets and reappends the key so the most recently used sits at the tail, put() evicts via array_shift which drops the least recently used head when over capacity. Effectively O(1) amortized.
edit_note
PHP Code Editor
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?php
final class LruCache {
private array $map = [];
public function __construct(private int $capacity) {
if ($capacity < 1) {
throw new InvalidArgumentException('capacity must be >= 1');
}
}
public function get(string $key): mixed {
if (!array_key_exists($key, $this->map)) {
return null;
}
$value = $this->map[$key];
unset($this->map[$key]);
$this->map[$key] = $value; // re-append as most recent
return $value;
}
public function put(string $key, mixed $value): void {
unset($this->map[$key]);
$this->map[$key] = $value;
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
settingsPHP Version
panorama_fish_eye
7.2
panorama_fish_eye
7.4
panorama_fish_eye
8.0
panorama_fish_eye
8.1
panorama_fish_eye
8.2
panorama_fish_eye
8.3
panorama_fish_eye
8.4
task_alt
8.5
terminal
Execution Result
play_circle_outline
Ready to execute
Click the "Run Script" button to see the output here
article
Description
A least-recently-used cache evicts the entry that has gone untouched the longest when it runs out of room. The textbook implementation pairs a hash map with a doubly linked list, but PHP arrays already maintain insertion order, so you can get the same behavior with far less code. The trick is to treat the front of the array as oldest and the back as newest.
On every get you remove the key and reinsert it, which moves it to the tail and marks it most recently used. On put, if you exceed capacity you array_shift the front, which is by construction the least recently used entry. This keeps both reads and writes constant time amortized and needs nothing beyond core PHP.
final class LruCache {
private array $map = [];
public function __construct(private int $capacity) {
if ($capacity < 1) {
throw new InvalidArgumentException('capacity must be >= 1');
}
}
public function get(string $key): mixed {
if (!array_key_exists($key, $this->map)) {
return null;
}
$value = $this->map[$key];
unset($this->map[$key]);
$this->map[$key] = $value; // re-append as most recent
return $value;
}
public function put(string $key, mixed $value): void {
unset($this->map[$key]);
$this->map[$key] = $value;
if (count($this->map) > $this->capacity) {
array_shift($this->map); // drop least recent
}
}
}
$cache = new LruCache(2);
$cache->put('a', 1);
$cache->put('b', 2);
$cache->get('a'); // touch a, now b is oldest
$cache->put('c', 3); // evicts b
echo $cache->get('a') . "\n"; // 1
var_dump($cache->get('b')); // NULL
echo $cache->get('c') . "\n"; // 3
Comments
No comments yet
Be the first to share your thoughts!