On this page
FileCache and ScopedCache
When your code needs a cache (compiled artifacts, parsed data, a build pipeline), use
Gacela\Framework\Cache\FileCache. It is the value layer of Gacela's caching. The framework puts
nothing in it; your application decides the keys, the values and the lifetimes.
FileCache
use Gacela\Framework\Cache\FileCache;
$cache = new FileCache('/var/cache/myapp');
$cache->put('user:42', $user, ttl: 600);
$cache->get('user:42'); // $user, or null after TTL expiry
$cache->forget('user:42');
$cache->clear();- One
.phpfile per key (SHA1-hashed), written atomically through a staged.tmpandrename. writeContentsAtomically(string $file, string $content): boolwrites already-rendered content to a path, with the same staged.tmpandrenameguarantees asput(). The higher-levelwriteAtomically()wraps it.- Each entry has its own TTL.
ttl: 0means forever; a negative TTL writes an entry that has already expired.InMemoryCacheStoragefollows the same rule as of 2.1. See the TTL contract. beginBatch()/commitBatch()hold writes back for a single flush under the index lock. Use them to warm many entries at once.stats()returns the entry count, total bytes, and the oldest and newest timestamps.- No torn reads: a concurrent reader sees either the previous file or the new one, never a half-written one.
ScopedCache: dependency-aware decorator
When invalidating one entry should also remove every entry derived from it, wrap FileCache in ScopedCache:
use Gacela\Framework\Cache\FileCache;
use Gacela\Framework\Cache\ScopedCache;
$cache = new ScopedCache(new FileCache('/var/cache/myapp'));
$cache->put('ns:core', $envCore);
$cache->put('file:a.php', $compiledA);
$cache->put('fragment:a#1', $fragment);
$cache->dependsOn('file:a.php', 'ns:core');
$cache->dependsOn('fragment:a#1', 'file:a.php');
$cache->invalidate('ns:core'); // cascades: file:a.php and fragment:a#1 also go
$cache->invalidateLeaf('file:a.php'); // only this key; dependents stay validget,putandhasgo straight to the underlyingFileCache, with zero overhead on the hot path.- The dependency graph is stored next to the values (
.gacela-scoped-cache-graph.php) and survives process restarts. dependsOn()rejects a cycle at once: self, two-node or transitive.- One writer at a time: when several processes race on
dependsOn(), edges added between load and persist may be lost. The value store underneath stays safe to read under concurrency either way.
See also
- Caching: the three caching layers and how to pick one
- Cacheable methods: caching Facade method results instead of raw values