zfegg / psr11-symfony-cache
Symfony Cache Component Factories for PSR-11
Requires
- php: ^8.2
- psr/container: ^1.0.0 | ^2.0
- symfony/cache: ^7.0
Requires (Dev)
- ext-couchbase: *
- ext-memcached: *
- ext-pdo: *
- ext-redis: *
- friendsofphp/php-cs-fixer: ^3.0
- laminas/laminas-servicemanager: ^4.1
- phpmd/phpmd: ^2.10
- phpstan/phpstan: ^0.12
- phpunit/phpunit: ^9.5
- predis/predis: ^1.1
- psr/simple-cache: ^1.0 || ^3.0
- squizlabs/php_codesniffer: ^3.6
README
Symfony Cache Component Factories for PSR-11.
Table of Contents
Installation
composer require zfegg/psr11-symfony-cache
Usage
<?php /** @var \Symfony\Component\Cache\Adapter\AdapterInterface $cache */ $cache = $container->get('other'); // The callable will only be executed on a cache miss. $value = $cache->get('my_cache_key', function (\Symfony\Contracts\Cache\ItemInterface $item) { $item->expiresAfter(3600); // ... do some HTTP request or heavy computations $computedValue = 'foobar'; return $computedValue; }); echo $value; // 'foobar'
Additional info can be found in the documentation
Containers
Any PSR-11 container wil work. In order to do that you will need to add configuration
and register a new service that points to Zfegg\Psr11SymfonyCache\CacheFactory
Below are some specific container examples to get you started
Pimple Example
// Create Container $container = new \Xtreamwayz\Pimple\Container([ // Cache using the default keys. 'cache' => new \Zfegg\Psr11SymfonyCache\CacheFactory(), // Second cache using a different cache configuration 'other' => function($c) { return \Zfegg\Psr11SymfonyCache\CacheFactory::other($c); }, // Config 'config' => [ 'cache' => [ // At the bare minimum you must include a default adaptor. 'default' => [ 'type' => '', 'options' => [], ], // Some other Adaptor. Keys are the names for each adaptor 'someOtherAdaptor' => [ 'type' => 'local', 'options' => [ 'root' => '/tmp/pimple' ], ], ], ] ]); /** @var \Symfony\Component\Cache\Adapter\AdapterInterface $cache */ $cache = $container->get('other'); // The callable will only be executed on a cache miss. $value = $cache->get('my_cache_key', function (\Symfony\Contracts\Cache\ItemInterface $item) { $item->expiresAfter(3600); // ... do some HTTP request or heavy computations $computedValue = 'foobar'; return $computedValue; }); echo $value; // 'foobar' // ... and to remove the cache key $cache->delete('my_cache_key');
Laminas Service Manager
// Create the container and define the services you'd like to use $container = new \Laminas\ServiceManager\ServiceManager([ 'factories' => [ // Cache using the default keys. 'fileSystem' => \Zfegg\Psr11SymfonyCache\CacheFactory::class, // Second cache using a different cache configuration 'other' => [\Zfegg\Psr11SymfonyCache\CacheFactory::class, 'other'], ], ]); // Config $container->setService('config', [ 'cache' => [ // At the bare minimum you must include a default adaptor. 'default' => [ 'type' => '', 'options' => [], ], // Some other Adaptor. Keys are the names for each adaptor 'someOtherAdaptor' => [ 'type' => 'local', 'options' => [ 'root' => '/tmp/pimple' ], ], ], ]); /** @var \Symfony\Component\Cache\Adapter\AdapterInterface $cache */ $cache = $container->get('other'); // The callable will only be executed on a cache miss. $value = $cache->get('my_cache_key', function (\Symfony\Contracts\Cache\ItemInterface $item) { $item->expiresAfter(3600); // ... do some HTTP request or heavy computations $computedValue = 'foobar'; return $computedValue; }); echo $value; // 'foobar' // ... and to remove the cache key $cache->delete('my_cache_key'); // CacheServiceAbstractFactory $container->addAbstractFactory(\Zfegg\Psr11SymfonyCache\CacheServiceAbstractFactory::class); $cacheDefault = $container->get("cache.default"); $cacheSomeOtherAdaptor = $container->get("cache.someOtherAdaptor"); // Get a psr 16 simple cache $psr16CacheDefault = $container->get("simple-cache.default"); $psr16CacheSomeOtherAdaptor = $container->get("simple-cache.someOtherAdaptor");
Frameworks
Any framework that use a PSR-11 should work fine. Below are some specific framework examples to get you started
Mezzio
You'll need to add configuration and register the services you'd like to use. There are number of ways to do that
but the recommended way is to create a new config file config/autoload/cache.global.php
Configuration
config/config.php
Add CacheServiceAbstractFactory
of ServiceManager
.
<?php $providers = [ // ... \Zfegg\Psr11SymfonyCache\ConfigProvider::class, ]
config/autoload/cache.global.php
<?php return [ 'dependencies' => [ 'factories' => [ // Cache using the default keys. 'fileSystem' => \Zfegg\Psr11SymfonyCache\CacheFactory::class, // Second cache using a different filesystem configuration 'someOtherAdaptor' => [\Zfegg\Psr11SymfonyCache\CacheFactory::class, 'someOtherAdaptor'], ], 'aliases' => [ \Psr\Cache\CacheItemPoolInterface::class => 'fileSystem', ], ], 'cache' => [ // At the bare minimum you must include a default adaptor. 'default' => [ 'type' => '', 'options' => [], ], // Some other Adaptor. Keys are the names for each adaptor 'someOtherAdaptor' => [ 'type' => 'local', 'options' => [ 'root' => '/tmp/pimple' ], ], ], ];
Laminas
You'll need to add configuration and register the services you'd like to use. There are number of ways to do that
but the recommended way is to create a new config file config/autoload/cache.global.php
Configuration
config/autoload/cache.global.php
<?php return [ 'service_manager' => [ 'factories' => [ // Cache using the default keys. 'fileSystem' => \Zfegg\Psr11SymfonyCache\CacheFactory::class, // Second cache using a different configuration 'someOtherAdaptor' => [\Zfegg\Psr11SymfonyCache\CacheFactory::class, 'someOtherAdaptor'], ], 'aliases' => [ \Psr\Cache\CacheItemPoolInterface::class => 'fileSystem', ], ], 'cache' => [ // At the bare minimum you must include a default adaptor. 'default' => [ 'type' => '', 'options' => [], ], // Some other Adaptor. Keys are the names for each adaptor 'someOtherAdaptor' => [ 'type' => 'local', 'options' => [ 'root' => '/tmp/pimple' ], ], ], ];
Slim
public/index.php
<?php use \Psr\Http\Message\ServerRequestInterface as Request; use \Psr\Http\Message\ResponseInterface as Response; use \Symfony\Component\Cache\Adapter\AdapterInterface; use \Symfony\Contracts\Cache\ItemInterface; require '../vendor/autoload.php'; // Add Configuration $config = [ 'settings' => [ 'cache' => [ // At the bare minimum you must include a default adaptor. 'default' => [ 'type' => '', 'options' => [], ], // Some other Adaptor. Keys are the names for each adaptor 'someOtherAdaptor' => [ 'type' => 'local', 'options' => [ 'root' => '/tmp/pimple' ], ], ], ], ]; $app = new \Slim\App($config); // Wire up the factory $container = $app->getContainer(); // Cache using the default keys. $container['fileSystem'] = new \Zfegg\Psr11SymfonyCache\CacheFactory(); // Second cache using a different cache configuration $container['someOtherAdaptor'] = function ($c) { return \Zfegg\Psr11SymfonyCache\CacheFactory::someOtherAdaptor($c); }; // Example usage $app->get('/example', function (Request $request, Response $response) { /** @var AdapterInterface $cache */ $cache = $this->get('other'); // The callable will only be executed on a cache miss. $value = $cache->get('my_cache_key', function (ItemInterface $item) { $item->expiresAfter(3600); // ... do some HTTP request or heavy computations $computedValue = 'foobar'; return $computedValue; }); echo $value; // 'foobar' // ... and to remove the cache key $cache->delete('my_cache_key'); }); $app->run();
Configuration
Minimal Configuration
A minimal configuration would consist of at least defining one service and the "default" adaptor.
Minimal Example (using Zend Expressive for the example)
<?php return [ 'cache' => [ 'default' => [ 'type' => '', 'options' => [], ], ], ];
Using this setup you will be using the "default" file system with the "default" adaptor. In this example we will be using the local file adaptor as the default.
Full Configuration
Note: A "default" adaptor is required.
Full Example
<?php return [ 'cache' => [ // At the bare minimum you must include a default adaptor. 'default' => [ 'type' => '', 'options' => [], ], // Some other Adaptor. Keys are the names for each adaptor 'someOtherAdaptor' => [ 'type' => 'local', 'options' => [ 'root' => '/tmp/pimple' ], ], ], ];
Adaptors
Example configs for supported adaptors
APCu
This adapter is a high-performance, shared memory cache. It can significantly increase an application’s performance, as its cache contents are stored in shared memory, a component appreciably faster than many others, such as the filesystem.
<?php return [ 'cache' => [ 'default' => [ 'type' => 'APCu', 'options' => [ 'namespace' => '', // Optional : a string prefixed to the keys of the items. 'defaultLifetime' => 0, // Optional : the default lifetime (in seconds) for cache items. Default: 0 'version' => null, // Optional : Version of the cache items. ], ], ], ];
Docs: APCu Cache Adapter
Array
Generally, this adapter is useful for testing purposes, as its contents are stored in memory and not persisted outside the running PHP process in any way. It can also be useful while warming up caches, due to the getValues() method
<?php return [ 'cache' => [ 'default' => [ 'type' => 'Array', 'options' => [ 'defaultLifetime' => 0, // Optional : the default lifetime (in seconds) for cache items. Default: 0 'storeSerialized' => true, // Optional : values saved in the cache are serialized before storing them Default: true 'maxLifetime' => 0, // Optional : the maximum lifetime (in seconds) of the entire cache. Default: 0 'maxItems' => 0, // Optional : the maximum number of items that can be stored in the cache. Default: 0 ], ], ], ];
Docs: APCu Cache Adapter
Chain
This adapter allows combining any number of the other available cache adapters. Cache items are fetched from the first adapter containing them and cache items are saved to all the given adapters. This exposes a simple and efficient method for creating a layered cache.
<?php return [ 'cache' => [ 'default' => [ 'type' => 'Chain', 'options' => [ 'adapters' => [], // Required : The ordered list of adapter service names to fetch cached items 'namespace' => '', // Optional : a string prefixed to the keys of the items. 'maxLifetime' => 0, // Optional : The max lifetime of items propagated from lower adapters to upper ones ], ], ], ];
Docs: Chain Cache Adapter
Couchbase
This adapter stores the values in-memory using one (or more) Couchbase server instances. Unlike the APCu adapter, and similarly to the Memcached adapter, it is not limited to the current server’s shared memory; you can store contents independent of your PHP environment. The ability to utilize a cluster of servers to provide redundancy and/or fail-over is also available.
<?php return [ 'cache' => [ 'default' => [ 'type' => 'Couchbase', 'options' => [ // Connection config // You must provide a client service, dsn(s) or connection information 'client' => 'service-name', // Couch Service name. Will be pulled from the container. 'dsn' => 'string or array', // Dsn for connections. Can be one dsn or an array of dsn's // Manual connection 'username' => 'username', // Required for manual connection 'password' => 'password', // Required for manual connection 'operationTimeout' => 2500000, // Optional. Default: 2500000 'configTimeout' => 5000000, // Optional. Default: 5000000 'configNodeTimeout' => 2000000, // Optional. Default: 2000000 'viewTimeout' => 75000000, // Optional. Default: 75000000 'httpTimeout' => 75000000, // Optional. Default: 75000000 'configDelay' => 10000, // Optional. Default: 10000 'htconfigIdleTimeout' => 4294967295, // Optional. Default: 4294967295 'durabilityInterval' => 100000, // Optional. Default: 100000 'durabilityTimeout' => 5000000, // Optional. Default: 5000000 // Cache Config 'namespace' => '', // Optional : a string prefixed to the keys of the items. 'maxLifetime' => 0, // Optional : The max lifetime of items propagated from lower adapters to upper ones ], ], ], ];
Docs: Couchbase Cache Adapter
Filesystem
This adapter offers improved application performance for those who cannot install tools like APCu or Redis in their environment. It stores the cache item expiration and content as regular files in a collection of directories on a locally mounted filesystem.
<?php return [ 'cache' => [ 'default' => [ 'type' => 'Filesystem', 'options' => [ 'directory' => '', // Optional : The main cache directory. Default: directory is created inside the system temporary directory 'namespace' => '', // Optional : a string prefixed to the keys of the items. 'defaultLifetime' => 0, // Optional : the default lifetime (in seconds) for cache items. Default: '0' ], ], ], ];
Docs: Filesystem Cache Adapter
Memcached
This adapter stores the values in-memory using one (or more) Memcached server instances. Unlike the APCu adapter, and similarly to the Redis adapter, it is not limited to the current server’s shared memory; you can store contents independent of your PHP environment. The ability to utilize a cluster of servers to provide redundancy and/or fail-over is also available.
<?php return [ 'cache' => [ 'default' => [ 'type' => 'Memcached', 'options' => [ // Connection config // A client service, or dsn(s). Default: localhost 'client' => 'service-name', // Memcached service name. Will be pulled from the container. 'dsn' => 'string or array', // Dsn for connections. Can be one dsn or an array of dsn's // Options 'auto_eject_hosts' => false, // Optional. Default: false 'buffer_writes' => false, // Optional. Default: false 'compression' => true, // Optional. Default: true 'compression_type' => 'fastlz', // Optional. Default: Varies based on flags used at compilation 'connect_timeout' => 1000, // Optional. Default: 1000 'distribution' => 'consistent', // Optional. Default: consistent 'hash' => 'md5', // Optional. Default: md5 'libketama_compatible' => true, // Optional. Default: true 'no_block' => true, // Optional. Default: true 'number_of_replicas' => 0, // Optional. Default: 0 'prefix_key' => '', // Optional. Default: empty string 'poll_timeout' => 1000, // Optional. Default: 1000 'randomize_replica_read' => false, // Optional. Default: false 'recv_timeout' => 0, // Optional. Default: 0 'retry_timeout' => 0, // Optional. Default: 0 'send_timeout' => 0, // Optional. Default: 0 'serializer' => 'php', // Optional. Default: php 'server_failure_limit' => 0, // Optional. Default: 0 'socket_recv_size' => 0, // Optional. Default: varies by platform and kernel 'socket_send_size' => 0, // Optional. Default: varies by platform and kernel 'tcp_keepalive' => false, // Optional. Default: false 'tcp_nodelay' => false, // Optional. Default: false 'use_udp' => false, // Optional. Default: false 'verify_key' => false, // Optional. Default: false // Cache Config 'namespace' => '', // Optional : a string prefixed to the keys of the items. 'maxLifetime' => 0, // Optional : The max lifetime of items propagated from lower adapters to upper ones ], ], ], ];
Docs: Memcached Cache Adapter
PDO and Doctrine DBAL
This adapter stores the cache items in an SQL database.
<?php return [ 'cache' => [ 'default' => [ 'type' => 'PDO', 'options' => [ 'client' => 'service-name', // Required: A client service, or dsn(s). 'db_table' => 'cache_items', // Optional. The name of the table. Default: cache_items 'db_id_col' => 'item_id', // Optional. The column where to store the cache id. Default: item_id 'db_data_col' => 'item_data', // Optional. The column where to store the cache data. Default: item_data 'db_lifetime_col' => 'item_lifetime', // Optional. The column where to store the lifetime. Default: item_lifetime 'db_time_col' => 'item_time', // Optional. The column where to store the timestamp. Default: item_time 'db_username' => '', // Optional. The username when lazy-connect 'db_password' => '', // Optional. The password when lazy-connect 'db_connection_options' => '', // Optional. An array of driver-specific connection options // Cache Config 'namespace' => '', // Optional : a string prefixed to the keys of the items. 'maxLifetime' => 0, // Optional : The max lifetime of items propagated from lower adapters to upper ones ], ], ], ];
Docs: PDO & Doctrine DBAL Cache Adapter
PHP Array
This adapter is a high performance cache for static data (e.g. application configuration) that is optimized and preloaded into OPcache memory storage. It is suited for any data that is mostly read-only after warmup.
<?php return [ 'cache' => [ 'default' => [ 'type' => 'PhpArray', 'options' => [ 'filePath' => __DIR__ . '/somefile.cache', // Required: Single file where values are cached 'backupCache' => 'service-name', // Required: A backup cache service ], ], ], ];
Docs: PHP Array Cache Adapter
PHP Files
Similarly to Filesystem Adapter, this cache implementation writes cache entries out to disk, but unlike the Filesystem cache adapter, the PHP Files cache adapter writes and reads back these cache files as native PHP code.
<?php return [ 'cache' => [ 'default' => [ 'type' => 'PhpFiles', 'options' => [ 'directory' => '/some/dir/path', // Required: The main cache directory (the application needs read-write permissions on it) // Cache Config 'namespace' => '', // Optional : a string prefixed to the keys of the items. 'maxLifetime' => 0, // Optional : The max lifetime of items propagated from lower adapters to upper ones ], ], ], ];
Docs: PHP Files Cache Adapter
Proxy
This adapter wraps a PSR-6 compliant cache item pool interface. It is used to integrate your application’s cache item pool implementation with the Symfony Cache Component by consuming any implementation of Psr\Cache\CacheItemPoolInterface.
It can also be used to prefix all keys automatically before storing items in the decorated pool, effectively allowing the creation of several namespaced pools out of a single one.
<?php return [ 'cache' => [ 'default' => [ 'type' => 'proxy', 'options' => [ 'psr6Service' => 'service-name', // Required: A PSR 6 cache service // Cache Config 'namespace' => '', // Optional : a string prefixed to the keys of the items. 'maxLifetime' => 0, // Optional : The max lifetime of items propagated from lower adapters to upper ones ], ], ], ];
Docs: Proxy Cache Adapter
Redis
This adapter stores the values in-memory using one (or more) Redis server instances.
Unlike the APCu adapter, and similarly to the Memcached adapter, it is not limited to the current server’s shared memory; you can store contents independent of your PHP environment. The ability to utilize a cluster of servers to provide redundancy and/or fail-over is also available.
<?php return [ 'cache' => [ 'default' => [ 'type' => 'Redis', 'options' => [ // Connection config // A client service, or dsn(s) is required. Default: localhost 'client' => 'service-name', // Redis service name. Will be pulled from the container. 'dsn' => 'redis://[pass@][ip|host|socket[:port]][/db-index]', // Dsn for connections. // Connection Options. Not needed if using a service. 'class' => '\Redis', // Optional. Specifies the connection library to return, either \Redis or \Predis\Client. Default: \Redis 'compression' => true, // Optional. Enables or disables compression of items. Default: true 'lazy' => false, // Optional. Enables or disables lazy connections to the backend. Default: false 'persistent' => 0, // Optional. Enables or disables use of persistent connections. Default: 0 'persistent_id' => 'some-id', // Optional. Specifies the persistent id string to use for a persistent connection. Default: null 'read_timeout' => 0, // Optional. Specifies the read timeout. Default: 0 'retry_interval' => 0, // Optional. Specifies the delay (in milliseconds) between reconnection attempts. Default: 0 'tcp_keepalive' => 0, // Optional. Specifies the TCP-keepalive timeout (in seconds) of the connection. Default: 0 'timeout' => 30, // Optional. Specifies the timeout (in seconds) used to connect to a Redis server. Default: 30 // Cache Config 'namespace' => '', // Optional : a string prefixed to the keys of the items. 'maxLifetime' => 0, // Optional : The max lifetime of items propagated from lower adapters to upper ones ], ], ], ];
Docs: Redis Cache Adapter
These docs, including the code samples, are licensed under a Creative Commons BY-SA 3.0 license.