A simple, secure, and highly customizable caching engine for PHP. This library provides time-based caching with built-in encryption support, making it suitable for application-level, server-level, and database-level caching scenarios.
- Instance-based API — fully DI-friendly, multiple cache pools can coexist
- Static facade (
CacheFacade) for quick usage without DI - Time-based caching with configurable TTL (Time-to-Live)
- Built-in encryption for sensitive data protection
- Multiple storage backends (File-based included, extensible via
Storageinterface) - Key prefixing for namespace isolation (
withPrefix()returns a new instance — no mutation) - Expired item cleanup via
purgeExpired() - Comprehensive error handling with custom exceptions
composer require webfiori/cacheThis library requires PHP 8.1 or higher.
| Build Status |
|---|
<?php
require_once 'vendor/autoload.php';
use WebFiori\Cache\Cache;
use WebFiori\Cache\FileStorage;
use WebFiori\Cache\KeyManager;
// Set up encryption key (recommended for production)
$_ENV['CACHE_ENCRYPTION_KEY'] = KeyManager::generateKey();
// Create a cache instance
$cache = new Cache(new FileStorage('/path/to/cache'));
// Store and retrieve
$cache->set('greeting', 'Hello, World!', 3600);
echo $cache->get('greeting'); // Hello, World!
// Auto-populate on cache miss using a generator callback
$data = $cache->get('user_data', function () {
return fetchUserDataFromDatabase();
}, 3600);
// Check, delete, flush
$cache->has('greeting'); // true
$cache->delete('greeting');
$cache->flush();For a complete runnable version of this, see the Set and Get example.
use WebFiori\Cache\Cache;
use WebFiori\Cache\FileStorage;
$cache = new Cache(new FileStorage('/path/to/cache'));
// Store with default TTL (60 seconds)
$cache->set('key', 'value');
// Store with custom TTL and override existing
$cache->set('key', 'new_value', 3600, true);
// Retrieve (returns null on miss)
$data = $cache->get('key');
// Generator with parameters
$profile = $cache->get('user_profile', function ($userId, $includePrefs) {
return fetchUserProfile($userId, $includePrefs);
}, 3600, [123, true]);
// Update TTL of existing item
$cache->setTTL('key', 7200);
// Enable/disable caching (useful for debugging)
$cache->setEnabled(false);Working examples for each operation: basic examples
withPrefix() returns a new Cache instance — the original is never mutated.
$users = $cache->withPrefix('users_');
$orders = $cache->withPrefix('orders_');
$users->set('count', 100, 60);
$orders->set('count', 250, 60);
$users->get('count'); // 100
$orders->get('count'); // 250
// Flush only one prefix
$users->flush();See Prefix Isolation and Prefix Flush.
For quick usage without dependency injection, use CacheFacade:
use WebFiori\Cache\CacheFacade;
CacheFacade::set('key', 'value', 60);
echo CacheFacade::get('key');
// withPrefix() returns a Cache instance
CacheFacade::withPrefix('users_')->set('count', 100, 60);All cached data is encrypted by default using AES-256-CBC. Configure via environment variables or programmatically:
# 64-character hexadecimal encryption key (required for encryption)
CACHE_ENCRYPTION_KEY=your64characterhexadecimalencryptionkeyhere1234567890abcdef
# Optional settings
CACHE_ENCRYPTION_ENABLED=true
CACHE_ENCRYPTION_ALGORITHM=aes-256-cbc
CACHE_FILE_PERMISSIONS=600
CACHE_DIR_PERMISSIONS=700use WebFiori\Cache\KeyManager;
// Generate and set a key programmatically
$key = KeyManager::generateKey();
KeyManager::setEncryptionKey($key);See Encryption Key Management, Security Config, and Encrypt/Decrypt Round-Trip.
Implement the Storage interface to create custom backends (e.g., Redis, Memcached, database):
use WebFiori\Cache\Storage;
use WebFiori\Cache\Item;
class MemoryStorage implements Storage {
public function store(Item $item) { /* ... */ }
public function read(string $key, ?string $prefix) { /* ... */ }
public function readItem(string $key, ?string $prefix): ?Item { /* ... */ }
public function has(string $key, ?string $prefix): bool { /* ... */ }
public function delete(string $key) { /* ... */ }
public function flush(?string $prefix) { /* ... */ }
public function purgeExpired(): int { /* ... */ }
}
$cache = new Cache(new MemoryStorage());Full working implementation: Custom Storage Driver.
| Method | Description | Returns |
|---|---|---|
get($key, $generator, $ttl, $params) |
Retrieve or create cache item | mixed |
set($key, $data, $ttl, $override) |
Store cache item | bool |
has($key) |
Check if item exists and is not expired | bool |
delete($key) |
Remove cache item | void |
flush() |
Clear all cache (respects current prefix) | void |
getItem($key) |
Get Item object with full metadata |
Item|null |
setTTL($key, $ttl) |
Update item TTL | bool |
isEnabled() / setEnabled($bool) |
Check or toggle caching | bool / void |
setDriver($driver) / getDriver() |
Set or get storage driver | void / Storage |
withPrefix($prefix) |
Returns new Cache instance with prefix |
Cache |
getPrefix() |
Get current prefix | string |
purgeExpired() |
Remove all expired items from storage | int |
Same methods as Cache, plus:
| Method | Description | Returns |
|---|---|---|
getInstance() |
Get the default Cache instance |
Cache |
setInstance($cache) |
Replace the default instance | void |
reset() |
Destroy the default instance (for testing) | void |
| Method | Description | Returns |
|---|---|---|
getKey() |
Get item key | string |
getData() / getDataDecrypted() / getDataEncrypted() |
Get raw, decrypted, or encrypted data | mixed / mixed / string |
getTTL() / setTTL($ttl) |
Get or set time-to-live | int / void |
getCreatedAt() / getExpiryTime() |
Get creation or expiry timestamp | int |
getSecurityConfig() / setSecurityConfig($config) |
Get or set security configuration | SecurityConfig / void |
generateKey() |
Generate encryption key (static) | string |
| Method | Description |
|---|---|
store(Item $item) |
Store cache item |
read(string $key, ?string $prefix) |
Read item data |
readItem(string $key, ?string $prefix) |
Read item as Item object |
has(string $key, ?string $prefix) |
Check item existence |
delete(string $key) |
Delete item |
flush(?string $prefix) |
Clear cache |
purgeExpired() |
Remove expired items, return count removed |
| Exception | When |
|---|---|
InvalidCacheKeyException |
Empty key, key > 250 chars, key with control characters |
CacheStorageException |
File system errors, invalid paths, permission issues |
CacheDriverException |
Invalid driver implementation |
CacheException |
Base exception, missing encryption key |
See Error Handling for all cases.
v3 changes Cache from a static singleton to an instance class. Migration is straightforward:
// v2 (static singleton) // v3 (instance-based)
Cache::set('k', 'v', 60); $cache = new Cache(new FileStorage($path));
Cache::get('k'); $cache->set('k', 'v', 60);
$cache->get('k');
Cache::withPrefix('x')->get('k'); $cache->withPrefix('x')->get('k');
// ⚠️ prefix leaked to all future calls // ✅ prefix is scoped, original unchanged
Cache::setDriver($driver); $cache = new Cache($driver);
Cache::create($driver, true, 'pfx'); new Cache($driver, true, 'pfx');If you prefer the static API, use CacheFacade — it works identically to v2's Cache:
use WebFiori\Cache\CacheFacade;
CacheFacade::set('k', 'v', 60);
CacheFacade::get('k');The examples/ directory contains 23 self-contained, runnable samples organized by difficulty:
Basic — Core operations every user needs:
| # | Example | What it demonstrates |
|---|---|---|
| 01 | Set and Get | set() and get() |
| 02 | Get with Generator | Auto-populate on cache miss |
| 03 | Generator with Params | Pass arguments to the callback |
| 04 | Check Existence | has() |
| 05 | Delete Item | delete() |
| 06 | Flush Cache | flush() |
| 07 | Update TTL | setTTL() |
| 08 | Override Behavior | set() with/without override |
| 09 | TTL Expiration | Items expire after TTL |
| 10 | Enable / Disable | Toggle caching on/off |
| 11 | Item Inspection | Read item metadata |
| 12 | Data Types | Strings, arrays, objects, edge cases |
Advanced — Security, extensibility, and error handling:
| # | Example | What it demonstrates |
|---|---|---|
| 01 | Prefix Isolation | Namespace isolation |
| 02 | Prefix Flush | Selective flush by prefix |
| 03 | Encryption Key Management | KeyManager usage |
| 04 | Security Config | Algorithm and permissions |
| 05 | Encryption Disabled | Store without encryption |
| 06 | Encrypt/Decrypt Round-Trip | Full encryption cycle |
| 07 | Custom Storage Driver | Implement Storage interface |
| 08 | File Storage Custom Path | Custom cache directory |
| 09 | File Permissions | Default and custom permissions |
| 10 | Error Handling | All exception types |
| 11 | Factory and DI | Constructor-based DI |
Run any example:
composer install
php examples/basic/01-set-and-get/index.phpThis library is licensed under MIT License. See LICENSE file for more details.
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests for new functionality
- Run the test suite:
composer test - Submit a pull request
- Issues: GitHub Issues
- Documentation: This README and examples/