PSR 16 简单缓存接口
本文档为缓存项目和缓存驱动程序定义了一个的简单可扩展的接口
本篇规范中的 必须,不得,需要,应,不应,应该,不应该,推荐,可能 和 可选 等词按照 RFC 2119 中的描述进行解释
最终的实现 可以 在此规范的基础上给对象添加更多的功能,但它们 必须 首先实现本文档的接口/功能
1. 规范
1.1 介绍
缓存是提高任何项目性能的常用方法,这使得使得缓存库成为许多框架和库中最常见的功能之一。
这个级别的互操作性意味着库可以移除它们自己的缓存实现,轻松的使用框架或其它专用的缓存库提供的缓存实现
PSR-6 已经解决了这个问题,但即使最简单的用例也需要的相当正式和冗长的方式
此规范提出的更简单的方式旨在为常见用例建立一个标准化的简化了的接口,此规范独立于 PSR-6,但同时尽可能简单的和 PSR-6 兼容
1.2 术语
调用库,实现库,TTL,过期和键,这些术语都从 PSR-6 复制,因为作出的假设条件都一样
-
「调用库」( Calling Library )
需要缓存服务的库或代码。这个库可以自由使用实现了此标准接口的缓存服务,而不需要知道这些缓存服务具体是如何实现的
-
「实现库」( Implementing Library )
实现了此缓存标准的类库,可以为任何 「调用库」提供缓存服务
实现库 必须 公开实现了
Cache\CacheItemPoolInterface
和Cache\ CacheItemInterface
接口的类实现库 必须 支持最低粒度的
TTL
功能,如下所述,也就是使用秒为单位的粒度 -
「存活时间」( TTL )
TTL 是
Time To Live
的缩写。一个项目 ( item ) 的 TTL 是指存储该项目的时间和过期时间之间的时间间隔。
TTL 通常使用以秒为单位的时间的整数或 DateInterval 对象来表示
-
「过期时间」( Expiration )
过期时间是项目 ( item ) 设置为过期的实际时间, 通常是项目的存储时间加上 TTL 计算得到的,但也可以显式的使用 DateTime 对象来设置。 一个在 1:30:00 存储的有着 300 秒 TTL 的项目 ( item ) 的过期时间是 1:35:00.
实现类库 可以 在项目要求的过期时间之前就将其过期,但只要达到过期时间,则 必须 视为过期。
如果调用库在保存项目时没有指定过期时间,或者指定了一个空的过期时间或 TTL,那么实现库 可以 使用配置的默认持续时间 ( TTL )
如果没有设置默认持续时间,那么实现库 必须 将其视为永久缓存该项目的请求,或者交给底层实现自行处理
-
「键」( Key )
键是由至少一个字符组成的,能够唯一标识缓存项的字符串
实现库 必须 支持 UTF-8 编码格式的,长度最多为 64 个字符组成的,由任意顺序的包括
A-Z
,a-z
,0-9
,_
和.
的字符组成的键实现库 可以 支持其它的字符或编码或更长的长度,但必须支持最小值
库可以自由决定如何转译键中的字符串,但 必须 能够返回原始的未修改的键
保留以下字符用于将来的扩展,实现类库绝对不能支持包含它们的任何键名
{} () / \ @ :
-
「缓存」( Cache )
实现了
Psr\SimpleCache\CacheInterface
接口的对象 -
「缓存丢失」( Cache Misses )
缓存丢失返回将返回空值 (
null
),因此检测是否存储null
空值是不可能的。这是与 PSR-6 假设的主要偏差
1.3 缓存
如果没有为某个具体的缓存项指定默认的 TTL,实现库 可以 为用户提供一种机制来指定默认的 TTL
如果用户没用配置默认值,实现库 必须 默认使用底层实现允许的最大值
如果底层实现不支持 TTL,则必须静默的忽略用户指定的 TTL
静默的意思,就是悄悄的忽略,不要抛出任何错误,也不要告诉用户我忽略了你设置的值啦
1.4 数据
实现库 必须 支持所有可序列化的 PHP 数据类型,包括 :
-
- 字符串 ( Strings )
- PHP 兼容的任意编码的任意大小的字符串
-
- 整数 ( Integers )
- PHP 支持的任意大小的所有整数,最高支持 64 位有符号整型
-
- 浮点数 ( Floats )
- 所有有符号的浮点数
-
- 布尔类型 ( Boolean )
TRUE
和FALSE
-
- NULL 值 ( Null )
- 实际意义上的空值
NULL
,虽然读取时很难将它与缓存丢失区分开来
-
- 数组 ( Arrays )
- 索引数组、关联数组、和任意维度的多维数组
-
- 对象 ( Object )
- 任何支持无损序列化和反序列化的对象,例如
$o == unserialize(serialize($o))
- 对象可以使用 PHP 的序列化接口、
__sleep()
或__wakeup()
、其它类似的语言功能
所有传递给实现库的数据 必须 原样返回,包括变量类型。 也就是说,如果保存时的数据为 (int) 5,而返回时的数据为 ( string ) 5 ,那么就是错误的。
实现库可以在内部使用 PHP 的 serialize()
/ unserialize()
函数 ,但并不强制要求这么做,但与它们保持兼容性是对可接受对象的一个基准要求
如果出于任何原因不能返回保存时的原值,实现库 必须 返回缓存丢失而不是损坏了的数据
2. 接口
2.1 CacheInterface
缓存接口定义了缓存实体集合的基本操作,包括基本的对单个缓存项的读,写和删除
此外,它还定义了操作多组缓存实体的方法,包括一次性的写入,读取或删除多个缓存条目。 当执行大量的缓存读取/写入操作时,这非常有用,并且你可以通过对缓存服务器的单个调用来执行你的操作,大大缩短延迟时间
CacheInterface
接口的实例对应于具有单个键名称空间的缓存项的单个集合,相当于 PSR-6 中的 「 池 」
不同的 CacheInterface
实例的后端 可以 是同一个数据存储,但逻辑上 必须 独立。
<?php namespace Psr\SimpleCache; interface CacheInterface { /** * 从缓存中获取缓存项的值 * * @param string $key 要获取的缓存项目的键 * @param mixed $default 如果键指定的缓存项不存在则返回该默认值 * * @return mixed 缓存项的值,如果缓存丢失,则返回传递的默认值 * * @throws \Psr\SimpleCache\InvalidArgumentException * 如果 $key 非法,则 **必须** 抛出此异常 */ public function get($key, $default = null); /** * 持久化缓存中保存的数据 * * @param string $key 要保存的缓存项的键 * @param mixed $value 要保存的缓存项的值,必须是可序列化的 * @param null|int|\DateInterval $ttl 可选. 当前缓存项的 TTL。 * 如果未指定此值且驱动程序支持 TTL * 那么库可以设定一个默认值或留给驱动程序自行处理 * * @return bool 成功返回 true ,失败返回 false * * @throws \Psr\SimpleCache\InvalidArgumentException * 如果 $key 非法,则 **必须** 抛出此异常 */ public function set($key, $value, $ttl = null); /** * 根据指定的键从缓存中删除缓存项 * * @param string $key 要删除的缓存项的键 * * @return bool 成功返回 true ,如果出错则返回 fasle * * @throws \Psr\SimpleCache\InvalidArgumentException * 如果 $key 不是一个合法的值,则 **必须** 抛出此异常 */ public function delete($key); /** * 清空缓存系统 * * @return bool 清空成功返回 true ,失败返回 false */ public function clear(); /** * 根据指定的键返回多个缓存项 * * @param iterable $keys 单个操作中获取的键的列表 * @param mixed $default 如果某个键的值的值不存在,则将此值作为该键的值 * * @return 可迭代的键值对列表. 如果某个键的值不存在,它仍然会使用 $default 作为其志 * * @throws \Psr\SimpleCache\InvalidArgumentException * 如果 $keys 不是一个数组或一个可迭代对象,或者 $keys 中的任何键非法 * 则 **必须** 抛出此异常 */ public function getMultiple($keys, $default = null); /** * 持久化一组键值对和可选的 TTL * * @param iterable $values 多个键值对的组成的列表 * @param null|int|\DateInterval $ttl 可选. 当前缓存项的 TTL。 * 如果未指定此值且驱动程序支持 TTL * 那么库可以设定一个默认值或留给驱动程序自行处理 * * @return bool 成功返回 true,失败返回 false * * @throws \Psr\SimpleCache\InvalidArgumentException * 如果 $values 不是一个数组或一个可迭代对象,或者 $values 中的任何键非法 * 则 **必须** 抛出此异常 */ public function setMultiple($values, $ttl = null); /** * 单次操作中删除多个缓存项 * * @param iterable $keys 要删除的字符串类型的键列表 * * @return bool 如果删除成功返回 true,如果发生错误则返回 false * * @throws \Psr\SimpleCache\InvalidArgumentException * 如果 $keys 不是一个数组或一个可迭代对象,或者 $keys 中的任何键非法 * 则 **必须** 抛出此异常 */ public function deleteMultiple($keys); /** * 判断缓存中是否包含某个数据 * * 注意:建议 has() 方法只用于缓存预处理等用途中且 * 不要用在实时应用程序中的 get/set 操作, * 因为此方法返回 true 的条件会在随后的另一个脚本立即执行的删除操作打破, * 使得缓存项的状态立刻过时 * * @param string $key 缓存数据的键名 * * @return bool * * @throws \Psr\SimpleCache\InvalidArgumentException * 如果字符串格式的键名 $key 不是合法的值则抛出此异常 */ public function has($key); }
2.2 CacheException
<?php namespace Psr\SimpleCache; /** * 所有缓存异常的基本接口 */ interface CacheException { }
2.3 InvalidArgumentException
<?php namespace Psr\SimpleCache; /** * 缓存参数无效时抛出的异常接口 * * 当传递的缓存参数无效时 **必须** 抛出实现了这个接口的异常 * this interface */ interface InvalidArgumentException extends CacheException { }