From a4510be4a2590cf82a30ae1bafe467f15adfd3da Mon Sep 17 00:00:00 2001 From: Luther Monson Date: Thu, 25 Jun 2026 21:51:28 -0700 Subject: [PATCH] feat: add flush() to KvOps trio (ephpm_kv_flush_all) Backfills flush() into the KV-ops trio (KvOpsInterface, SapiKvOps, InMemoryKvOps) now that ePHPm v0.1.2 ships the ephpm_kv_flush_all(): bool SAPI function. SapiKvOps::flush() calls it behind a function_exists() guard so older runtimes return false instead of fataling. KvSessionHandler deliberately does NOT expose flush() through its public surface: a global flush wipes more than just session keys (no SCAN means we can't enumerate by prefix), and the recommended wholesale-invalidation pattern remains 'bump the prefix in config and let TTLs age the old sessions out'. The flush method is available at the ops layer for anyone driving SapiKvOps directly, and for parity with the other ephpm cache packages. --- src/InMemoryKvOps.php | 7 +++++++ src/KvOpsInterface.php | 11 +++++++++++ src/SapiKvOps.php | 8 ++++++++ tests/InMemoryKvOpsTest.php | 11 +++++++++++ 4 files changed, 37 insertions(+) diff --git a/src/InMemoryKvOps.php b/src/InMemoryKvOps.php index 80b6504..3a0d0d4 100644 --- a/src/InMemoryKvOps.php +++ b/src/InMemoryKvOps.php @@ -96,6 +96,13 @@ public function pttl(string $key): int return \max(0, $this->deadlines[$key] - $this->nowMs()); } + public function flush(): bool + { + $this->values = []; + $this->deadlines = []; + return true; + } + /** * Resolve a key's value, expiring it lazily if its deadline has passed. */ diff --git a/src/KvOpsInterface.php b/src/KvOpsInterface.php index 6624c6b..c0a3cc0 100644 --- a/src/KvOpsInterface.php +++ b/src/KvOpsInterface.php @@ -73,4 +73,15 @@ public function ttl(string $key): int; * -2 if the key does not exist, otherwise the ms remaining. */ public function pttl(string $key): int; + + /** + * Remove every key from the effective store. Backed by ephpm_kv_flush_all() + * (ePHPm v0.1.2+); a no-op returning false on older runtimes. + * + * Note: this is a *global* flush — it drops more than just session + * keys. KvSessionHandler deliberately does not expose this; the + * recommended way to invalidate every session is to bump the handler's + * prefix in config and let TTLs age the old entries out. + */ + public function flush(): bool; } diff --git a/src/SapiKvOps.php b/src/SapiKvOps.php index 7907bf8..473b047 100644 --- a/src/SapiKvOps.php +++ b/src/SapiKvOps.php @@ -63,4 +63,12 @@ public function pttl(string $key): int { return (int) \ephpm_kv_pttl($key); } + + public function flush(): bool + { + if (!\function_exists('ephpm_kv_flush_all')) { + return false; + } + return (bool) \ephpm_kv_flush_all(); + } } diff --git a/tests/InMemoryKvOpsTest.php b/tests/InMemoryKvOpsTest.php index 3a5b225..fbb2f59 100644 --- a/tests/InMemoryKvOpsTest.php +++ b/tests/InMemoryKvOpsTest.php @@ -108,4 +108,15 @@ public function test_expire_with_zero_or_negative_is_noop(): void // Original TTL unchanged. self::assertGreaterThan(0, $ops->pttl('k')); } + + public function test_flush_clears_values_and_deadlines(): void + { + $ops = new InMemoryKvOps(); + $ops->set('a', 'one'); + $ops->set('b', 'two', 60); + self::assertTrue($ops->flush()); + self::assertNull($ops->get('a')); + self::assertNull($ops->get('b')); + self::assertSame(-2, $ops->pttl('b')); + } }