phpdot / cache
PSR-16 cache with pluggable drivers for modern PHP.
v0.1.1
2026-07-18 18:54 UTC
Requires
- php: >=8.5
- psr/simple-cache: ^3.0
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.94
- phpdot/container: ^0.1
- phpstan/phpstan: ^2.0
- phpstan/phpstan-strict-rules: ^2.0
- phpunit/phpunit: ^13.0
README
PSR-16 cache with pluggable drivers — Redis, File, Array, APCu, Null — and a remember()
pattern. Standalone.
Table of Contents
Requirements
| Requirement | Constraint |
|---|---|
| PHP | >= 8.5 |
psr/simple-cache |
^3.0 |
| ext-redis | for RedisDriver |
| ext-apcu | for ApcuDriver |
| ext-igbinary | optional — faster serialization |
Installation
composer require phpdot/cache
Usage
Basic
use PHPdot\Cache\Store; use PHPdot\Cache\Driver\RedisDriver; $cache = new Store(new RedisDriver($redis, prefix: 'app:')); $cache->set('user:1', $userData, 3600); $user = $cache->get('user:1'); $cache->delete('user:1'); $cache->has('user:1'); // false
Remember pattern
$user = $cache->remember('user:1', 3600, function () use ($db) { return $db->table('users')->find(1); }); // First call: queries DB, caches result // Subsequent calls: returns from cache $config = $cache->rememberForever('app:config', fn() => loadConfig());
Swap backends
$cache = new Store(new RedisDriver($redis, prefix: 'app:')); $cache = new Store(new FileDriver('/var/cache/app')); $cache = new Store(new ArrayDriver()); $cache = new Store(new ApcuDriver(prefix: 'app:')); $cache = new Store(new NullDriver()); // Same API, different backend
Batch operations
$cache->setMultiple([ 'user:1' => $user1, 'user:2' => $user2, ], ttl: 3600); $users = $cache->getMultiple(['user:1', 'user:2', 'user:3'], default: null); $cache->deleteMultiple(['user:1', 'user:2']);
LRU eviction (ArrayDriver)
$cache = new Store(new ArrayDriver(maxItems: 1000)); // Evicts least recently used entry when full
Custom driver
use PHPdot\Cache\DriverInterface; final class MongoDriver implements DriverInterface { // Implement 8 methods: get, set, delete, clear, has, // getMultiple, setMultiple, deleteMultiple } $cache = new Store(new MongoDriver($collection));
Drivers
| Driver | Backend | Serialization | Shared | Use case |
|---|---|---|---|---|
RedisDriver |
ext-redis | igbinary/serialize | Yes | Production, distributed |
FileDriver |
Filesystem | igbinary/serialize | Yes (disk) | Single server, no Redis |
ArrayDriver |
PHP array | None | No (per-worker) | Testing, short-lived |
ApcuDriver |
ext-apcu | None (SHM) | Yes (per-server) | Single server, fast reads |
NullDriver |
None | None | N/A | Testing, disabled cache |
PSR-16 Compliance
Store implements Psr\SimpleCache\CacheInterface:
- Key validation: rejects
{}()/\@:characters and empty strings - TTL normalization: accepts
int,DateInterval, ornull - Negative TTL treated as expired
- Throws
PHPdot\Cache\Exception\InvalidArgumentExceptionfor invalid keys
Notes
remember() and null values: PSR-16 cannot distinguish between "key not found" and "key stores null". If a remember() callback returns null, the callback will run on every call. Use false or a sentinel value instead of null for cacheable "empty" results.
Architecture
graph TD
S[Store] -->|PSR-16| DI[DriverInterface]
S -->|remember / rememberForever| DI
DI --> RD[RedisDriver]
DI --> FD[FileDriver]
DI --> AD[ArrayDriver]
DI --> APD[ApcuDriver]
DI --> ND[NullDriver]
DI --> CD[Custom Driver]
RD -->|serialize| SER[Serializer]
FD -->|serialize| SER
style S fill:#2d3748,color:#fff
style DI fill:#4a5568,color:#fff
style RD fill:#718096,color:#fff
style FD fill:#718096,color:#fff
style AD fill:#718096,color:#fff
style APD fill:#718096,color:#fff
style ND fill:#718096,color:#fff
style CD fill:#718096,color:#fff
style SER fill:#718096,color:#fff
Loading
Testing
The package is standalone-testable:
composer install composer test # PHPUnit (driver tests skip when ext-redis/ext-apcu are absent) composer analyse # PHPStan, level max + strict rules composer cs-check # PHP-CS-Fixer composer check # All three
License
MIT.
This repository is a read-only mirror, generated by CI from phpdot/monorepo. Pull requests and issues belong in the monorepo.