PSR-6:缓存接口

缓存接口

缓存是提高任何项目性能的常用方法,使缓存库成为许多框架和库的最常见功能之一。这导致了许多库推出自己的缓存库,具有各种级别的功能。这些差异导致开发人员必须学习多个系统,这些系统可能会也可能不会提供他们所需的功能。此外,缓存库本身的开发人员面临着只支持有限数量的框架或创建大量适配器类的选择。

缓存系统的通用接口将解决这些问题。库和框架开发人员可以按照他们期望的方式依赖缓存系统,而缓存系统的开发人员只需要实现一组接口而不是各种各样的适配器。

本文件中的关键词“必须”,“不得”,“必须”,“应该”,“不应该”,“应该”,“不应该”,“推荐”,“可以”和“可选”按照RFC 2119中的描述进行解释

目标

此PSR的目标是允许开发人员创建可以集成到现有框架和系统中的缓存感知库,而无需自定义开发。

定义

  • 调用库 - 实际需要缓存服务的库或代码。该库将利用实现此标准接口的缓存服务,但不会知道这些缓存服务的实现。

  • 实现库 - 该库负责实现此标准,以便为任何调用库提供缓存服务。实现库必须提供实现Cache \ CacheItemPoolInterface和Cache \ CacheItemInterface接口的类。实现库必须支持至少TTL功能,如下所述,具有全秒级粒度。

  • TTL - 项目的生存时间(TTL)是该项目存储与被视为陈旧之间的时间量。TTL通常由表示以秒为单位的时间的整数或DateInterval对象定义。

  • 到期 - 项目设置为过时的实际时间。这通常通过将TTL添加到存储对象的时间来计算,但也可以使用DateTime对象显式设置。在1:30:00存储300秒TTL的项目将到期为1:35:00。实现库可能会在其请求的到期时间之前使项目到期,但是一旦达到其到期时间,必须将项目视为已过期。如果调用库要求保存项目但未指定过期时间,或指定空过期时间或TTL,则实现库可以使用配置的默认持续时间。如果没有设置默认持续时间,则实现库必须将其解释为永久缓存项目的请求,或者只要底层实现支持。

  • 密钥 - 至少一个字符的字符串,用于唯一标识缓存的项目。实施库必须支持由字符的键A-Za-z0-9_,和.在以UTF-8编码的任何顺序和最多64个字符的长度。实现库可以支持其他字符和编码或更长的长度,但必须至少支持该最小值。库负责自己的密钥字符串转义,但必须能够返回原始未修改的密钥字符串。以下字符保留用于将来的扩展,并且实现库不得支持:{}()/\@:

  • 命中 - 当调用库按键请求Item并且找到该键的匹配值并且该值未过期时,会发生缓存命中,并且由于某些其他原因该值无效。调用库应该确保在所有get()调用上验证isHit()。

  • Miss - 缓存未命中与缓存命中相反。当调用库按键请求项目并且找不到该键的值,或者找到但已过期的值,或者由于某些其他原因该值无效时,会发生缓存未命中。过期的值必须始终被视为缓存未命中。

  • 递延 - 延迟缓存保存表示池可能不会立即保留缓存项。Pool对象可以延迟持久化延迟缓存项目,以便利用某些存储引擎支持的批量设置操作。池必须确保最终持久化任何延迟缓存项并且数据不会丢失,并且可以在调用库请求它们被持久化之前保留它们。当调用库调用commit()方法时,所有未完成的延迟项必须保持不变。实现库可以使用适当的逻辑来确定何时持久化延迟项,例如对象析构函数,持久保存save(),超时或最大项检查或任何其他适当的逻辑。对已延迟的缓存项的请求必须返回延迟但尚未持久的项。

数据

实现库必须支持所有可序列化的PHP数据类型,包括:

  • 字符串 - 任何PHP兼容编码中任意大小的字符串。
  • 整数 - PHP支持的任何大小的所有整数,最多64位有符号。
  • 花车 -所有签署浮点值。
  • 布尔 - 真和假。
  • Null - 实际的空值。
  • 数组 - 任意深度的索引,关联和多维数组。
  • Object - 支持无损序列化和反序列化的任何对象,例如$ o == unserialize(serialize($ o))。对象可以利用PHP的Serializable接口,__sleep()或者__wakeup()魔术方法,或者如果合适的话类似的语言功能。

传递到实现库的所有数据必须完全按照传递的方式返回。这包括变量类型。也就是说,如果(int)5是保存的值则返回(字符串)5是错误的。实现库可以在内部使用PHP的serialize()/ unserialize()函数,但不是必须这样做。与它们的兼容性仅用作可接受对象值的基线。

如果由于任何原因无法返回确切的保存值,则实现库必须以缓存未命中而不是损坏的数据进行响应。

关键概念

池表示缓存系统中的项目集合。池是它包含的所有项的逻辑存储库。所有可缓存项都作为Item对象从Pool中检索,并且与整个Universe缓存对象的所有交互都通过Pool进行。

项目

Item表示池中的单个键/值对。键是Item的主要唯一标识符,必须是不可变的。价值可以随时更改。

错误处理

虽然缓存通常是应用程序性能的重要组成部分,但它永远不应成为应用程序功能的关键部分。因此,缓存系统中的错误不应导致应用程序失败。出于这个原因,实现库绝不能抛出除接口定义的异常之外的异常,并且应该捕获由底层数据存储触发的任何错误或异常,并且不允许它们冒泡。

实施库应该记录这些错误或以适当方式将其报告给管理员。

如果调用库请求删除一个或多个项目,或者清除池,则如果指定的键不存在,则不得将其视为错误条件。后置条件相同(密钥不存在,或者池为空),因此没有错误条件。

接口

CacheItemInterface

CacheItemInterface定义缓存系统内的项。每个Item对象必须与一个特定的键相关联,该键可以根据实现系统进行设置,并且通常由Cache \ CacheItemPoolInterface对象传递。

Cache \ CacheItemInterface对象封装了缓存项的存储和检索。每个Cache \ CacheItemInterface都由Cache \ CacheItemPoolInterface对象生成,该对象负责任何所需的设置以及将对象与唯一Key相关联。Cache \ CacheItemInterface对象必须能够存储和检索本文档“数据”部分中定义的任何类型的PHP值。

调用库绝不能实例化Item对象本身。它们只能通过getItem()方法从Pool对象请求。调用库不应该假设一个实现库创建的项与另一个实现库中的池兼容。

<?php

namespace Psr\Cache;

/**
 * CacheItemInterface defines an interface for interacting with objects inside a cache.
 */
interface CacheItemInterface
{
    /**
     * Returns the key for the current cache item.
     *
     * The key is loaded by the Implementing Library, but should be available to
     * the higher level callers when needed.
     *
     * @return string
     *   The key string for this cache item.
     */
    public function getKey();

    /**
     * Retrieves the value of the item from the cache associated with this object's key.
     *
     * The value returned must be identical to the value originally stored by set().
     *
     * If isHit() returns false, this method MUST return null. Note that null
     * is a legitimate cached value, so the isHit() method SHOULD be used to
     * differentiate between "null value was found" and "no value was found."
     *
     * @return mixed
     *   The value corresponding to this cache item's key, or null if not found.
     */
    public function get();

    /**
     * Confirms if the cache item lookup resulted in a cache hit.
     *
     * Note: This method MUST NOT have a race condition between calling isHit()
     * and calling get().
     *
     * @return bool
     *   True if the request resulted in a cache hit. False otherwise.
     */
    public function isHit();

    /**
     * Sets the value represented by this cache item.
     *
     * The $value argument may be any item that can be serialized by PHP,
     * although the method of serialization is left up to the Implementing
     * Library.
     *
     * @param mixed $value
     *   The serializable value to be stored.
     *
     * @return static
     *   The invoked object.
     */
    public function set($value);

    /**
     * Sets the expiration time for this cache item.
     *
     * @param \DateTimeInterface|null $expiration
     *   The point in time after which the item MUST be considered expired.
     *   If null is passed explicitly, a default value MAY be used. If none is set,
     *   the value should be stored permanently or for as long as the
     *   implementation allows.
     *
     * @return static
     *   The called object.
     */
    public function expiresAt($expiration);

    /**
     * Sets the expiration time for this cache item.
     *
     * @param int|\DateInterval|null $time
     *   The period of time from the present after which the item MUST be considered
     *   expired. An integer parameter is understood to be the time in seconds until
     *   expiration. If null is passed explicitly, a default value MAY be used.
     *   If none is set, the value should be stored permanently or for as long as the
     *   implementation allows.
     *
     * @return static
     *   The called object.
     */
    public function expiresAfter($time);

}

CacheItemPoolInterface

Cache \ CacheItemPoolInterface的主要目的是接受来自调用库的密钥并返回关联的Cache \ CacheItemInterface对象。它也是与整个缓存集合交互的主要点。池的所有配置和初始化都由实现库决定。

<?php

namespace Psr\Cache;

/**
 * CacheItemPoolInterface generates CacheItemInterface objects.
 */
interface CacheItemPoolInterface
{
    /**
     * Returns a Cache Item representing the specified key.
     *
     * This method must always return a CacheItemInterface object, even in case of
     * a cache miss. It MUST NOT return null.
     *
     * @param string $key
     *   The key for which to return the corresponding Cache Item.
     *
     * @throws InvalidArgumentException
     *   If the $key string is not a legal value a \Psr\Cache\InvalidArgumentException
     *   MUST be thrown.
     *
     * @return CacheItemInterface
     *   The corresponding Cache Item.
     */
    public function getItem($key);

    /**
     * Returns a traversable set of cache items.
     *
     * @param string[] $keys
     *   An indexed array of keys of items to retrieve.
     *
     * @throws InvalidArgumentException
     *   If any of the keys in $keys are not a legal value a \Psr\Cache\InvalidArgumentException
     *   MUST be thrown.
     *
     * @return array|\Traversable
     *   A traversable collection of Cache Items keyed by the cache keys of
     *   each item. A Cache item will be returned for each key, even if that
     *   key is not found. However, if no keys are specified then an empty
     *   traversable MUST be returned instead.
     */
    public function getItems(array $keys = array());

    /**
     * Confirms if the cache contains specified cache item.
     *
     * Note: This method MAY avoid retrieving the cached value for performance reasons.
     * This could result in a race condition with CacheItemInterface::get(). To avoid
     * such situation use CacheItemInterface::isHit() instead.
     *
     * @param string $key
     *   The key for which to check existence.
     *
     * @throws InvalidArgumentException
     *   If the $key string is not a legal value a \Psr\Cache\InvalidArgumentException
     *   MUST be thrown.
     *
     * @return bool
     *   True if item exists in the cache, false otherwise.
     */
    public function hasItem($key);

    /**
     * Deletes all items in the pool.
     *
     * @return bool
     *   True if the pool was successfully cleared. False if there was an error.
     */
    public function clear();

    /**
     * Removes the item from the pool.
     *
     * @param string $key
     *   The key to delete.
     *
     * @throws InvalidArgumentException
     *   If the $key string is not a legal value a \Psr\Cache\InvalidArgumentException
     *   MUST be thrown.
     *
     * @return bool
     *   True if the item was successfully removed. False if there was an error.
     */
    public function deleteItem($key);

    /**
     * Removes multiple items from the pool.
     *
     * @param string[] $keys
     *   An array of keys that should be removed from the pool.

     * @throws InvalidArgumentException
     *   If any of the keys in $keys are not a legal value a \Psr\Cache\InvalidArgumentException
     *   MUST be thrown.
     *
     * @return bool
     *   True if the items were successfully removed. False if there was an error.
     */
    public function deleteItems(array $keys);

    /**
     * Persists a cache item immediately.
     *
     * @param CacheItemInterface $item
     *   The cache item to save.
     *
     * @return bool
     *   True if the item was successfully persisted. False if there was an error.
     */
    public function save(CacheItemInterface $item);

    /**
     * Sets a cache item to be persisted later.
     *
     * @param CacheItemInterface $item
     *   The cache item to save.
     *
     * @return bool
     *   False if the item could not be queued or if a commit was attempted and failed. True otherwise.
     */
    public function saveDeferred(CacheItemInterface $item);

    /**
     * Persists any deferred cache items.
     *
     * @return bool
     *   True if all not-yet-saved items were successfully saved or there were none. False otherwise.
     */
    public function commit();
}

CacheException

此异常接口旨在用于发生严重错误时,包括但不限于缓存设置,如连接到缓存服务器或提供的无效凭据。

实现库抛出的任何异常都必须实现此接口。

<?php

namespace Psr\Cache;

/**
 * Exception interface for all exceptions thrown by an Implementing Library.
 */
interface CacheException
{
}

InvalidArgumentException

<?php

namespace Psr\Cache;

/**
 * Exception interface for invalid cache arguments.
 *
 * Any time an invalid argument is passed into a method it must throw an
 * exception class which implements Psr\Cache\InvalidArgumentException.
 */
interface InvalidArgumentException extends CacheException
{
}