webfiori/cache

A simple caching engine which is highly customizable.

Maintainers

Package info

github.com/WebFiori/cache

pkg:composer/webfiori/cache

Statistics

Installs: 1 949

Dependents: 1

Suggesters: 0

Stars: 0

Open Issues: 1

3.0.0 2026-04-20 20:40 UTC

This package is auto-updated.

Last update: 2026-04-20 20:44:27 UTC


README

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.

Features

  • 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 Storage interface)
  • Key prefixing for namespace isolation (withPrefix() returns a new instance — no mutation)
  • Expired item cleanup via purgeExpired()
  • Comprehensive error handling with custom exceptions

Installation

composer require webfiori/cache

Supported PHP Versions

This library requires PHP 8.1 or higher.

Build Status

Quick Start

<?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.

Usage

Basic Operations

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

Prefix Isolation

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.

Static Facade

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);

Security & Encryption

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=700
use 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.

Custom Storage Drivers

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.

API Reference

Cache Class (Instance Methods)

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

CacheFacade Class (Static Methods)

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

Item Class

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

Storage Interface

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

Error Handling

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.

Upgrading from v2

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');

Examples

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.php

License

This library is licensed under MIT License. See LICENSE file for more details.

Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes
  4. Add tests for new functionality
  5. Run the test suite: composer test
  6. Submit a pull request

Support