decodelabs / stash
PSR6 / PSR16 cache handler
Installs: 4 036
Dependents: 4
Suggesters: 0
Security: 0
Stars: 0
Watchers: 2
Forks: 0
Open Issues: 0
Requires
- php: ^8.4
- decodelabs/archetype: ^0.4
- decodelabs/atlas: ^0.14
- decodelabs/coercion: ^0.3.5
- decodelabs/dictum: ^0.7
- decodelabs/exceptional: ^0.6.3
- decodelabs/kingdom: ^0.2
- decodelabs/monarch: ^0.2
- nesbot/carbon: ^3
- psr/cache: ^3.0
- psr/simple-cache: ^3.0
Requires (Dev)
- ext-apcu: ^5.1
- ext-memcached: ^3.2
- ext-redis: ^5.3|^6
- decodelabs/commandment: ^0.3.0
- decodelabs/genesis: ^0.14
- decodelabs/phpstan-decodelabs: ^0.7
- predis/predis: ^2.4
Suggests
- ext-apcu: For APCu support
- ext-memcached: For memcached support
- ext-redis: For redis support
- decodelabs/dovetail: For dovetail config integration
- predis/predis: For redis support
Provides
Conflicts
- decodelabs/genesis: <0.14
This package is auto-updated.
Last update: 2025-09-17 11:02:16 UTC
README
Cache storage system
Stash provides a PSR6 / PSR16 compatible cache system for PHP.
Installation
composer require decodelabs/stash
Usage
Store and access data in a standardised volatile cache either via the PSR6 or PSR16 interface mechanisms. Caches are namespaced to allow for clean separation of data between usage domains.
use DecodeLabs\Stash; $stash = new Stash(); $myCache = $stash->load('MyCache'); if(!$myCache->has('myValue')) { $myCache->set('myValue', [1, 2, 3]); } $total = 0; foreach($myCache->get('myValue', []) as $number) { $total += $number; } $myCache->delete('myValue');
Fetch
Use the fetch method to ensure a cache value is in place in one call:
$myValue = $myCache->fetch('myValue', function() { return [1, 2, 3]; // Only called if key not found in cache });
Array Access
Array access methods provide quick offset access to cache data:
if(!isset($myCache['myValue'])) { $myCache['myValue'] = 'Hello world'; } echo $myCache['myValue']; unset($MyCache['myValue']);
Object access
Object access works the same way as ArrayAccess, but with the PSR6 Cache Item object as the return:
$item = $myCache->myValue; if(!$item->isHit()) { $item->set('Hello world'); } echo $item->get(); $item->delete();
Drivers
The following drivers are available out of the box:
- Memcache
- Redis
- Predis (native PHP redis client)
- APCu
- File (serialized data)
- PhpFile (var_export data)
- PhpArray (in memory)
- Blackhole (nothing stored)
Stash uses Archetype to load driver classes so additional drivers may be provided by implementing your own Resolver
.
If no configuration is provided, Stash will attempt to use the best-fit driver for your environment, starting with Memcache, through Redis and APCu, and falling back on the File store.
Configuration
Stash can be configured by passing a DriverManager
to the constructor (or in your DI container):
use DecodeLabs\Stash\DriverManager; $stash = new Stash(new DriverManager( new RedisConfig('localRedis'), new RedisConfig('anotherRedis', host: '123.456.789.000', port: 6379), new MemcacheConfig('remoteMemcache', host: '123.456.789.000', port: 11211), new NamespaceConfig('MyStore', driver: 'remoteMemcache'), new FileStoreConfig('specialFileStore', path: '/tmp/stash/fileStore'), ));
You may pass any number of DriverConfig
, NamespaceConfig
and FileStoreConfig
objects to the DriverManager
to configure the drivers and stores - the DriverManager
will use the most relevant driver for each namespace.
If you're using Kingdom
to manage your application, it is advisable to provide a DriverManager
to your container and specify the drivers you want to use during initialization.
use DecodeLabs\Fabric\Kingdom as FabricKingdom; use DecodeLabs\Kingdom\ContainerAdapter; use DecodeLabs\Stash\DriverManager; use DecodeLabs\Stash\DriverConfig\Redis as RedisConfig; class Kingdom extends FabricKingdom { public function initialize(): void { parent::initialize(); $this->container->setFactory( DriverManager::class, fn () => new DriverManager( new RedisConfig('localRedis') ) ); } }
Custom Store methods
By default, newly loaded caches use a generic Store implementation, however if you require custom methods for domain-oriented data access, you can implement your own Store classes using a custom Archetype Resolver
.
namespace MyApp; use DecodeLabs\Stash\Store; use DecodeLabs\Stash\Store\Generic; class MyCache extends Generic { public function getMyData(): string { return $this->fetch('myData', function() { return 'Hello world'; }); } } $archetype->map(Store::class, namespace::class); $myCache = $stash->load('MyCache'); // Will now use MyApp\MyCache
Licensing
Stash is licensed under the MIT License. See LICENSE for the full license text.