Skip to content

Instantly share code, notes, and snippets.

@dragoonis
Created June 26, 2013 11:51
Show Gist options
  • Save dragoonis/5866827 to your computer and use it in GitHub Desktop.
Save dragoonis/5866827 to your computer and use it in GitHub Desktop.

Common Interface for Caching libraries

This document describes a simple yet extensible interface for a cache item and a cache driver.

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119.

The final implementations MAY be able to decorate the objects with more functionality than the one proposed but they MUST implement the indicated interfaces/functionality first.

  1. Specification

1.1 Introduction

Caching is a common way to improve the performance of any project, making caching libraries one of the most common features of many frameworks and libraries. This has led to a situation where many libraries roll their own caching libraries, with various levels of functionality. These differences are causing developers to have to learn multiple systems which may or may not provide the functionality they need. In addition, the developers of caching libraries themselves face a choice between only supporting a limited number of frameworks or creating a large number of adapter classes.

A common interface for caching systems will solve these problems. Library and framework developers can count on the caching systems working the way they're expecting, while the developers of caching systems will only have to implement a single set of interfaces rather than a whole assortment of adapters.

1.2 Definitions

  • TTL - The Time To Live (TTL) of an item is the amount of time between when that item is stored and it is considered stale. The TTL is normally defined by an integer representing time in seconds.

  • Expiration - The actual time when an item is set to go stale.

An item with a 300 second TTL stored at 1:30:00 will have an expiration at
1:35:00.
  • Key - A string that uniquely identifies the cached item.

  • CacheItem - An object that implements the Psr\Cache\ItemInterface interface.

  • Cache - An object that implements the Psr\Cache\CacheInterface interface.

1.3 Cache

Implementations MAY provide a mechanism for a user to specify a default TTL if one is not specified for a specific cache item. If no user-specified default is provided implementations MUST default to the maximum legal value allowed by the underlying implementation. If the underlying implementation does not support TTL, the user-specified TTL MUST be silently ignored.

If your implementation is expected to work accross many different platforms then it is recommended to have your cache keys consist of no more than 32 ASCII characters or the following symbols. ,._-

  1. Interfaces

2.1 ItemInterface

By using the CacheItem class implementations can guarantee consistency across various systems.

The CacheItem objects are generated by the Cache class. CacheItem objects encapsulate the key and value of the stored cache entry. CacheItem objects SHOULD NOT be created in any other way.

<?php

namespace Psr\Cache;

interface ItemInterface
{

    /**
     * Get the key associated with this CacheItem
     *
     * @return string
     */
    public function getKey();

    /**
     * Obtain the value of this cache item
     *
     * @return mixed
     */
    public function getValue();

    /**
     * This boolean value tells us if our cache item is currently in the cache or not
     *
     * @return boolean
     */
    public function isHit();

}

2.2 CacheInterface

This is the base interface class that developers should be looking to begin with. It provised provides the most basic functionality imaginable by a cache server which entails basic reading, writing and deleting of cache items. It will provide a generic API for library developers to allow applications to communicate to all popular cache backends.

<?php

namespace Psr\Cache;

use Psr\Cache\ItemInterface;

interface CacheInterface
{

    /**
     * Here we pass in a cache key to be fetched from the cache.
     * A CacheItem object will be constructed and returned to us
     *
     * @param string $key The unique key of this item in the cache
     *
     * @return CacheItemInterface The newly populated CacheItem class representing the stored data in the cache
     */
    public function get($key);

    /**
     * Persisting our data in the cache, uniquely referenced by a key with an optional expiration TTL time.
     *
     * @param string       $key   The key of the item to store
     * @param mixed        $value The value of the item to store
     * @param null|integer $ttl   Optional. The TTL value of this item. If no value is sent and the driver supports TTL
     *                            then the library may set a default value for it or let the driver take care of that.
     *
     * @return boolean True on success and false otherwise
     */
    public function set($key, $value, $ttl = null);

    /**
     * Remove an item from the cache by its unique key
     *
     * @param string $key The unique cache key of the item to remove
     *
     * @return boolean    Returns true on success and otherwise false
     */
    public function remove($key);

    /**
     * This will wipe out the entire cache's keys
     *
     * @return boolean Returns true on success and otherwise false
     */
    public function clear();

}

2.3 MultipleInterface

This interface has methods for dealing with multiple sets of cache entries such as writing, reading or deleting multiple cache entries at a time. This is really useful when you have lots of cache reads/writes to perform then you can perform your operations in a single call to the cache server cutting down latency times dramatically.

<?php

namespace Psr\Cache;

interface MultipleInterface
{

    /**
     * Obtain multiple CacheItems by their unique keys
     *
     * @param array $keys A list of keys that can obtained in a single operation.
     *
     * @return array An array of CacheItem classes.
     *               The resulting array must use the CacheItem's key as the associative key for the array.
     */
    public function getMultiple($keys);

    /**
     * Persisting a set of key => value pairs in the cache, with an optional TTL.
     *
     * @param array        $items An array of key => value pairs for a multiple-set operation.
     * @param null|integer $ttl   Optional. The TTL value of this item. If no value is sent and the driver supports TTL
     *                            then the library may set a default value for it or let the driver take care of that.
     *
     * @return boolean The result of the multiple-set operation
     */
    public function setMultiple($items, $ttl = null);

    /**
     * Remove multiple cache items in a single operation
     *
     * @param array $keys The array of keys to be removed
     *
     * @return array An array of 'key' => result, elements. Each array row has the key being deleted
     *               and the result of that operation. The result will be a boolean of true or false
     *               representing if the cache item was removed or not
     */
    public function removeMultiple($keys);

}

2.4 IncrementableInterface

This interface provides the ability to increment and decrement cache entries by their specified value. Some cache backends support this natively so that you don't have to read the item and then increment it and write it back to the cache server, this can be done in a single call to the cache server since it's natively supported by many modern cache servers.

<?php

namespace Psr\Cache;

interface IncrementableInterface
{

    /**
     * Increment a value in the cache by its step value, which defaults to 1
     *
     * @param string  $key  The cache item key
     * @param integer $step The value to increment by, defaulting to 1
     *
     * @return boolean True on success and false on failure
     */
    public function increment($key, $step = 1);
    
    /**
     * Decrement a value in the cache by its step value, which defaults to 1
     *
     * @param string  $key  The cache item key
     * @param integer $step The value to decrement by, defaulting to 1
     *
     * @return boolean True on success and false on failure
     */
    public function decrement($key, $step = 1);

}

2.5 CacheAwareInterface

This class allows any generic PHP class to become cache aware. This means it can be used to detect if an instance knows about PSR\Cache and can have PSR\Cache instances injected into it the setCache method

<?php

namespace Psr\Cache;

interface CacheAwareInterface
{
    /**
     * Sets a cache instance on the object
     *
     * @param CacheInterface $cache
     * @return null
     */
    public function setCache(CacheInterface $cache);
}
  1. Package

The interfaces described as well as a test suite to verify your implementation are provided as part of the psr/cache package.

  1. Credits

Parts of this proposal is the result of many months of deliberation, team work and proposals which can be referenced here:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment