koded/cache-simple

A PSR-16 caching library with support for several caching technologies. Supports JSON data caching in Redis.

3.1.0 2023-10-16 19:58 UTC

README

Latest Stable Version Build Status Code Coverage Scrutinizer Code Quality Packagist Downloads Minimum PHP Version

A PSR-16 caching library for PHP 8 using several caching technologies. It supports JSON caching for Redis.

Requirements

The library is not tested on any Windows OS and may not work as expected there.

The recommended installation method is via Composer

composer require koded/cache-simple

Redis

There are two client flavors for Redis by using the

and they are not mutually exclusive.

These clients supports JSON serialization for the cache, useful for handling the cached data in other programming languages.

Since there is no Redis native support for JSON serialization, it's done in userland and that always introduces some overhead. Be aware that the native PHP and Igbinary functions are superior.

  • the RedisClient is preferred if Redis extension is installed
  • the PredisClient can be used otherwise
// with Redis extension
simple_cache_factory('redis');

// with Predis library
simple_cache_factory('predis');

Memcached

Please install the Memcached extension.

Usage

The factory function always creates a new instance of specific SimpleCacheInterface client implementation.

/*
 * Creates a simple cache instance
 * with MemcachedClient and default configuration
 */

$cache = simple_cache_factory('memcached');
/*
 * Some configuration directives for the cache client
 * are passed in the second argument as array
 */

$cache = simple_cache_factory('redis', [
    'host'       => '127.0.0.1',
    'serializer' => 'json',
    'prefix'     => 'test:',
    'ttl'        => 3600 // 1 hour global TTL
]);

A bit verbose construction for the same instance is

$config = new ConfigFactory(['serializer' => 'json', 'prefix' => 'test:', 'ttl' => 3000]);
$cache = (new ClientFactory($config))->new('redis');

Configuration directives

Current available configuration classes

RedisConfiguration

Please refer to Redis extension connect method.

Parameter Value
host 127.0.0.1
port 6379
timeout 0.0
reserved null
retry 0
// Without defining the parameters the above directives are used as default
$cache = simple_cache_factory('redis');

Serializers

  • php (default)
  • json

The special config directive is binary(string) for setting the internal serializer functions to either PHP native un/serialize(), igbinary_un/serialize() or msgpack_un/pack().

$cache = simple_cache_factory('redis', [
    'binary' => \Koded\Stdlib\Serializer::MSGPACK
]);

The binary directive is effective if igbinary and/or msgpack extensions are installed and loaded. Otherwise it defaults to PHP un/serialize() functions.

You can change the binary flag on already cached data, but you should invalidate the previously cached items, since they are already serialized and stored in the cache.

JSON serializer options

The default options for json_encode() function are:

  • JSON_PRESERVE_ZERO_FRACTION
  • JSON_UNESCAPED_SLASHES
  • JSON_THROW_ON_ERROR

To set the desired options, use the options configuration directive:

$cache = simple_cache_factory('redis', [
    'serializer' => 'json',
    'options' => JSON_UNESCAPED_SLASHES | JSON_FORCE_OBJECT
]);

JSON options are applied with bitmask operators. The above example will

  • remove JSON_UNESCAPED_SLASHES (because it's already set)
  • add JSON_FORCE_OBJECT

MemcachedConfiguration

Memcached arguments Type Required Description
id string no Memcached persistent_id value
servers array no A list of nested array with [server, port] values
options array no A list of Memcached options
ttl int no Global TTL (in seconds)

The following options are set by default when an instance of MemcachedConfiguration is created, except for OPT_PREFIX_KEY which is there as a reminder that it may be set.

Memcached option Default value
OPT_DISTRIBUTION DISTRIBUTION_CONSISTENT
OPT_SERVER_FAILURE_LIMIT 2
OPT_REMOVE_FAILED_SERVERS true
OPT_RETRY_TIMEOUT 1
OPT_LIBKETAMA_COMPATIBLE true
OPT_PREFIX_KEY null

Options with NULL value will be removed.

There are many Memcached options that may suit the specific needs for the caching scenarios and this is something the developer/s needs to figure it out.

Examples:

[
    // Memcached client `persistent_id`
    'id' => 'items',

    // your Memcached servers list
    'servers' => [
        ['127.0.0.1', 11211],
        ['127.0.0.2', 11211],
        ['127.0.0.2', 11212],
    ],

    // Memcached client options
    'options' => [
        \Memcached::OPT_PREFIX_KEY            => 'i:',  // cache item prefix
        \Memcached::OPT_REMOVE_FAILED_SERVERS => false, // changes the default value
        \Memcached::OPT_DISTRIBUTION          => null   // remove this directive with NULL
    ],

    // the global expiration time (for ALL cached items)
    'ttl' => 120,
]

PredisConfiguration

By default the parameters are:

Parameter Value
scheme tcp
host 127.0.0.1
port 6379

Examples:

$cache = simple_cache_factory('predis');
$cache = simple_cache_factory('predis', [
    'scheme' => 'unix',
    'path' => '/path/to/redis.sock',
    'options' => [
        'prefix' => 'i:',
        'exceptions' => true,
        'parameters' => [
            'password' => getenv('REDIS_PASSWORD'),
            'database' => 1
        ]
    ]
]);

There are many configuration options for this package. Please refer to Predis configuration page.

Shared Memory (shmop)

Requires a PHP shmop extension.

$cache = simple_cache_factory('shmop', [
    'dir' => '/path/to/app/cache', // optional
    'ttl' => null,                 // global TTL
]);

FileConfiguration

Please avoid it on production environments, or use it as a last option.

If cache directory is not provided in the configuration, the PHP function sys_get_temp_dir() is used to store the cached files in the OS "temporary" directory.

$cache = simple_cache_factory('file', ['dir' => '/tmp']);

MemoryClient

This client will store the cached items in the memory for the duration of the script's lifetime. It is useful for development, but not for production.

MemoryClient is also the default client if you do not require a specific client in cache_simple_factory()

$cache = simple_cache_factory('memory');
$cache = simple_cache_factory();  // also creates a MemoryClient

Code quality

vendor/bin/phpunit
vendor/bin/phpbench run --report=default --group=factory
vendor/bin/phpbench run --report=default --group=read-write

or

vendor/bin/phpbench run --report=benchmark --group=read-write

Benchmarks

The benchmarks are flaky and dependant on the environment. This table gives a non-accurate insight how client performs at write-read-delete operations, and should have an informative comparison.

To find out what may be the fastest choice for your environment, run

vendor/bin/phpbench run --report=default --group=read-write

+-----------------+-----------+-----------+-----------+--------+
| subject         | best      | mean      | worst     | rstdev |
+-----------------+-----------+-----------+-----------+--------+
| bench_predis    | 1.354ms   | 1.403ms   | 1.431ms   | ±2.49% |
| bench_redis     | 581.000μs | 592.667μs | 609.000μs | ±2.01% |
| bench_memcached | 581.000μs | 593.333μs | 606.000μs | ±1.72% |
| bench_file      | 355.000μs | 367.667μs | 385.000μs | ±3.45% |
| bench_shmop     | 349.000μs | 364.000μs | 374.000μs | ±2.97% |
| bench_memory    | 77.000μs  | 79.667μs  | 82.000μs  | ±2.58% |
+-----------------+-----------+-----------+-----------+--------+

License

Software license

The code is distributed under the terms of The 3-Clause BSD license.