-
Notifications
You must be signed in to change notification settings - Fork 0
Cache
Razy provides a PSR-16 compatible caching layer with a static facade, pluggable storage adapters, and file-validation support. The Cache system supports File, Redis, APCu, and Null adapters out of the box.
use Razy\Cache;
use Razy\Cache\FileAdapter;
// Initialize with file adapter
Cache::initialize('/path/to/cache', new FileAdapter('/path/to/cache'));
// Store and retrieve values
Cache::set('user.profile.123', $userData, ttl: 3600);
$profile = Cache::get('user.profile.123');
// Check existence
if (Cache::has('user.profile.123')) {
// cached
}
// Delete
Cache::delete('user.profile.123');The Cache facade must be initialized before use. If not initialized, it auto-initializes with a NullAdapter (no-op):
use Razy\Cache;
use Razy\Cache\FileAdapter;
use Razy\Cache\RedisAdapter;
// File-based cache
Cache::initialize('/var/cache/razy', new FileAdapter('/var/cache/razy'));
// Redis-based cache
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
Cache::initialize('', new RedisAdapter($redis, 'myapp_'));
// Check status
Cache::isInitialized(); // true
// Enable/disable at runtime (disabled = NullAdapter behavior)
Cache::setEnabled(false);
Cache::isEnabled(); // false
// Swap adapter at runtime
Cache::setAdapter(new RedisAdapter($redis));
// Get current adapter
$adapter = Cache::getAdapter();All operations follow the PSR-16 SimpleCacheInterface contract:
use Razy\Cache;
// SET → store a value with optional TTL
Cache::set('key', 'value'); // no expiry
Cache::set('key', 'value', 3600); // expires in 1 hour (seconds)
Cache::set('key', 'value', new DateInterval('PT1H')); // DateInterval TTL
// GET → retrieve with optional default
$value = Cache::get('key'); // returns null if missing
$value = Cache::get('key', 'fallback'); // returns 'fallback' if missing
// HAS → check existence
if (Cache::has('key')) {
// ...
}
// DELETE → remove a single entry
Cache::delete('key');
// CLEAR → remove all entries
Cache::clear();Efficiently read/write multiple keys in a single call:
// SET multiple values
Cache::setMultiple([
'user.1' => $user1,
'user.2' => $user2,
'user.3' => $user3,
], ttl: 3600);
// GET multiple values
$users = Cache::getMultiple(['user.1', 'user.2', 'user.3']);
// Returns: ['user.1' => $user1, 'user.2' => $user2, 'user.3' => $user3]
// GET with default for missing keys
$users = Cache::getMultiple(['user.1', 'user.999'], default: null);
// Returns: ['user.1' => $user1, 'user.999' => null]
// DELETE multiple
Cache::deleteMultiple(['user.1', 'user.2']);A unique Razy feature that ties cached data to a source file's modification time. If the file changes, the cache is automatically invalidated:
// Cache compiled template → auto-invalidates when template.html changes
Cache::setValidated(
key: 'template.compiled.main',
filePath: '/path/to/template.html',
data: $compiledTemplate,
ttl: 86400
);
// Retrieve → returns null if file has been modified since caching
$compiled = Cache::getValidated(
key: 'template.compiled.main',
filePath: '/path/to/template.html'
);
if ($compiled === null) {
// File changed or cache expired → recompile
$compiled = compileTemplate('/path/to/template.html');
Cache::setValidated('template.compiled.main', '/path/to/template.html', $compiled);
}How it works: setValidated() stores the file's mtime alongside the cached data. getValidated() compares the stored mtime with the current file's mtime → if they differ, the cache entry is considered stale and returns $default.
Directory-sharded file cache with atomic writes. Files are stored as {dir}/{xx}/{md5}.cache:
use Razy\Cache\FileAdapter;
$adapter = new FileAdapter('/var/cache/razy');
// All PSR-16 methods available
$adapter->set('key', 'value', 3600);
$value = $adapter->get('key');
// File-specific extras
$stats = $adapter->getStats();
// Returns: ['directory' => '/var/cache/razy', 'files' => 142, 'size' => 1048576]
// Garbage collection → removes expired entries, returns count removed
$removed = $adapter->gc();Features:
-
Atomic writes via temp file + rename (crash-safe)
-
Two-character directory sharding (e.g.
ab/abcdef123456.cache) -
Lazy purge on read (expired entries deleted when accessed)
-
Windows-compatible file handling
-
Key validation rejects PSR-16 reserved characters:
{}()/\@:
High-performance Redis-backed cache:
use Razy\Cache\RedisAdapter;
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
$redis->auth('password');
$redis->select(2);
$adapter = new RedisAdapter($redis, prefix: 'myapp_');
// Access underlying Redis instance
$redis = $adapter->getRedis();Features:
-
Configurable key prefix (default:
'razy_') -
serialize/unserializefor complex PHP values -
Batch
getMultipleuses RedisMGETfor efficiency -
clear()with prefix usesSCANto delete only prefixed keys (safe for shared Redis)
Shared memory cache via APCu extension:
use Razy\Cache\ApcuAdapter;
// Requires ext-apcu
$adapter = new ApcuAdapter(prefix: 'myapp_');Features:
-
High performance (shared memory, no I/O)
-
clear()usesAPCuIteratorwith prefix regex to only clear own entries -
Best for single-server deployments
No-op adapter for testing or disabled cache mode:
use Razy\Cache\NullAdapter;
$adapter = new NullAdapter();
$adapter->get('key'); // always returns default
$adapter->set('key', 1); // always returns true
$adapter->has('key'); // always returns falseAll Cache facade operations wrap adapter calls in try/catch(\Throwable). If an adapter throws (e.g. Redis connection lost), the operation fails silently and returns the default/false:
// Even if Redis is down, this won't crash your application
$value = Cache::get('key', 'fallback'); // returns 'fallback'
Cache::set('key', 'value'); // returns falseWhen the cache is disabled via Cache::setEnabled(false), all operations behave as if using the NullAdapter.
| Method | Signature | Description |
| --- | --- | --- |
| initialize | (string $cacheDir, ?CacheInterface $adapter): void | Set up cache system |
| isInitialized | (): bool | Check if initialized |
| setEnabled | (bool $enabled): void | Enable/disable caching |
| isEnabled | (): bool | Check if enabled |
| getAdapter | (): CacheInterface | Get current adapter |
| setAdapter | (CacheInterface $adapter): void | Swap adapter |
| get | (string $key, mixed $default = null): mixed | Retrieve value |
| set | (string $key, mixed $value, int\|DateInterval\|null $ttl = null): bool | Store value |
| delete | (string $key): bool | Remove entry |
| clear | (): bool | Remove all entries |
| has | (string $key): bool | Check existence |
| getMultiple | (iterable $keys, mixed $default = null): iterable | Batch retrieve |
| setMultiple | (iterable $values, int\|DateInterval\|null $ttl = null): bool | Batch store |
| deleteMultiple | (iterable $keys): bool | Batch remove |
| getValidated | (string $key, string $filePath, mixed $default = null): mixed | File-validated get |
| setValidated | (string $key, string $filePath, mixed $data, int\|DateInterval\|null $ttl = null): bool | File-validated set |
| reset | (): void | Reset facade state |
| Method | Signature | Description |
| --- | --- | --- |
| getStats | (): array{directory, files, size} | Cache directory statistics |
| gc | (): int | Garbage collect expired entries |