Caching

Services\Cache implements PSR-16's CacheInterface directly — the standard get(), set(), delete(), has(), getMultiple(), setMultiple(), deleteMultiple(), clear(). Because CacheInterface is an instance interface, Cache is one of the handful of Clarity services you instantiate yourself rather than call statically — see Service Container for the full list and why most services are different.

Three drivers, one instance each

The driver is a constructor argument. One Cache instance is bound to one driver — to use two drivers in the same app, construct two instances:

use Monad\Clarity\Services\Cache;

$fileCache = new Cache(driver: Cache::DRIVER_FILE, path: '/absolute/path/to/storage/cache');
$dbCache = new Cache(driver: Cache::DRIVER_DATABASE);
$redisCache = new Cache(driver: Cache::DRIVER_REDIS, redis: $redisConnection);
  • File (/storage/cache) — single-node only, by nature of local disk.
  • Database (the caches table) — shared across nodes.
  • Redis — shared, external service; accepts anything exposing get/set/setex/del/exists/keys, not hard-typed to ext-redis's \Redis class.

Using it

$cache->set('homepage.view_count', 1042, ttl: 3600); // seconds, or a DateInterval
$views = $cache->get('homepage.view_count', default: 0);

$cache->setMultiple(['a' => 1, 'b' => 2]);
$cache->getMultiple(['a', 'b', 'missing'], default: 0); // ['a' => 1, 'b' => 2, 'missing' => 0]

$cache->delete('homepage.view_count');
$cache->has('homepage.view_count'); // false

The database driver's collision-defense rule

The caches table's primary key is key_hash (a SHA-256 hash of the cache key) rather than the key itself — this sidesteps long-key index limits. But the driver never trusts the hash alone: every read also compares the row's stored cache_key against the requested key, and a mismatch is treated as a miss, exactly as a hash collision would demand, whether or not one has actually occurred. This is a correctness rule, not a performance one — cheap to check, and makes the driver provably correct against a theoretical collision rather than merely unlikely to be wrong.

Next steps

  • Service Container — why Cache is instantiated instead of called statically.
  • Deployment — which driver to pick for horizontal scaling.