kuria / cache
具有驱动抽象的缓存库
Requires
- php: >=7.1.0
- kuria/clock: ^1.0
- kuria/event: ^2.0
- kuria/iterable: ^1.0
Requires (Dev)
- kuria/dev-meta: ^0.6
- php-mock/php-mock-phpunit: ^2.1.1
- psr/cache: ^1.0
- psr/simple-cache: ^1.0
Suggests
- psr/cache: to use the PSR-6 cache component (^1.0)
- psr/simple-cache: to use the PSR-16 simple cache component (^1.0)
Provides
README
具有驱动抽象的缓存库。
内容
- 特性
- 要求
- 内置驱动程序
- 用法
- 创建缓存实例
- 缓存方法
setPrefix()
- 配置缓存前缀getNamespace()
- 获取命名空间缓存实例has()
- 检查条目是否存在get()
- 读取单个条目getMultiple()
- 读取多个条目listKeys()
- 列出缓存中的键getIterator()
- 列出缓存中的键和值add()
/set()
- 创建新条目addMultiple()
/setMultiple()
- 创建多个条目cached()
- 缓存回调函数的结果delete()
- 删除条目deleteMultiple()
- 删除多个条目filter()
- 使用前缀删除条目clear()
- 删除所有条目cleanup()
- 清理缓存
- 允许的值类型
- 缓存事件
- PSR-6: 缓存适配器
- PSR-16: 简单缓存包装器
特性
- 条目操作:has, add, set, get, delete
- 多条目操作:获取、设置、添加、删除
- 列表、过滤、清理(需要驱动程序支持)
- TTL 过期
- 键前缀/命名空间
- 存储和检索的值可以通过事件进行操作
- PSR-6 缓存适配器
- PSR-16 简单缓存包装器
- 多个内置驱动程序实现
要求
- PHP 7.1+
内置驱动程序
注意
如果驱动程序不支持原生的多读/写/删除,缓存将模拟多读/写/删除。
用法
创建缓存实例
文件系统
将缓存条目以二进制文件的形式存储在指定的目录中。
<?php use Kuria\Cache\Cache; use Kuria\Cache\Driver\Filesystem\FilesystemDriver; $driver = new FilesystemDriver(__DIR__ . '/cache'); $cache = new Cache($driver);
注意
如果需要,可以通过 CRON 或类似机制定期调用 $cache->cleanup()
来物理删除文件系统中的过期条目。
将缓存条目作为 PHP 文件存储
将缓存条目作为实际的 PHP 文件(而不是二进制文件)存储可能更有益,这样它们可以被 opcache(例如 opcache)拾取以提高性能。
<?php use Kuria\Cache\Cache; use Kuria\Cache\Driver\Filesystem\Entry\File\PhpFileFormat; use Kuria\Cache\Driver\Filesystem\FilesystemDriver; $driver = new FilesystemDriver( __DIR__ . '/cache', FilesystemDriver::createEntryFactory(new PhpFileFormat()) ); $cache = new Cache($driver);
提示
以这种方式缓存大量数据时,请确保已正确配置 opcode 缓存。
对于 opcache,最相关的设置是 opcache.memory_consumption
和 opcache.max_accelerated_files
。
警告
要充分利用 opcode 缓存,PhpFileFormat
使用 var_export()
而不是 serialize()
。只有实现 __set_state() 方法的对象才能存储在缓存中。
APCu
使用 APCu 存储缓存条目。
<?php use Kuria\Cache\Cache; use Kuria\Cache\Driver\Apcu\ApcuDriver; $cache = new Cache(new ApcuDriver());
Memcached
使用 Memcached 存储缓存条目。
<?php use Kuria\Cache\Cache; use Kuria\Cache\Driver\Memcached\MemcachedDriver; $memcached = new \Memcached(); $memcached->addServer('localhost', 11211); $cache = new Cache(new MemcachedDriver($memcached));
Redis
使用 PhpRedis 存储缓存条目。
<?php use Kuria\Cache\Cache; use Kuria\Cache\Driver\Redis\RedisDriver; $redis = new \Redis(); $redis->connect('localhost', 6380); // might return FALSE.. $cache = new Cache(new RedisDriver($redis));
内存
在内存中存储缓存条目。
这些条目仅在脚本执行期间可用,并且线程之间不共享。
<?php use Kuria\Cache\Cache; use Kuria\Cache\Driver\Memory\MemoryDriver; $cache = new Cache(new MemoryDriver());
注意
已过期的条目不会从内存中清除,直到尝试访问它们。可以通过调用$cache->cleanup()
来立即清除所有已过期的条目。
黑洞
存储的条目将立即丢弃。这对于测试或调试很有用。
<?php use Kuria\Cache\Cache; use Kuria\Cache\Driver\BlackHole\BlackHoleDriver; $cache = new Cache(new BlackHoleDriver());
缓存方法
setPrefix()
- 配置缓存前缀
setPrefix()
方法定义了一个前缀,该前缀将在将所有键传递给底层驱动实现之前应用。
前缀可以是一个空字符串,以禁用此功能。
<?php $cache->setPrefix('prefix_');
getNamespace()
- 获取命名空间缓存实例
getNamespace()
方法返回一个缓存实例,该实例在将所有键传递给原始缓存之前应用一个前缀。
<?php $fooCache = $cache->getNamespace('foo.'); $fooCache->get('bar'); // reads foo.bar $fooCache->delete('baz'); // deletes foo.baz $fooCache->clear(); // deletes foo.* (if the cache is filterable) // etc.
has()
- 检查条目是否存在
has()
方法返回TRUE
或FALSE
,指示条目是否存在。
<?php if ($cache->has('key')) { echo 'Entry exist'; } else { echo 'Entry does not exist'; }
警告
注意has()
和get()
调用之间可能存在竞态条件。
如果可能,请只调用get()
并检查其结果是否为NULL
,或使用其$exists
参数。
get()
- 读取单个条目
get()
方法返回存储的值或不存在条目时返回NULL
。
<?php $value = $cache->get('key');
如果您需要区分NULL
值和不存在条目,请使用$exists
参数。
<?php $value = $cache->get('key', $exists); if ($exists) { // entry was found // $value might be NULL if NULL was stored } else { // entry was not found }
getMultiple()
- 读取多个条目
getMultiple()
方法返回一个键值映射。不存在的键将具有NULL
值。
<?php $values = $cache->getMultiple(['foo', 'bar', 'baz']);
如果您需要区分NULL
值和不存在条目,请使用$failedKeys
参数。
<?php $values = $cache->getMultiple(['foo', 'bar', 'baz'], $failedKeys); // $failedKeys will contain a list of keys that were not found
listKeys()
- 列出缓存中的键
listKeys()
方法将返回缓存中键的可迭代列表,可选地匹配一个公共前缀。
如果驱动程序不支持此操作,将抛出UnsupportedOperationException
异常。您可以使用isFilterable()
方法检查支持。
<?php if ($cache->isFilterable()) { // list all keys foreach ($cache->listKeys() as $key) { echo "{$key}\n"; } // list keys beginning with foo_ foreach ($cache->listKeys('foo_') as $key) { echo "{$key}\n"; } }
getIterator()
- 列出缓存中的键和值
getIterator()
方法将返回缓存中所有键和值的迭代器。这是IteratorAggregate
接口的一部分。
如果驱动程序不支持此操作,将抛出UnsupportedOperationException
异常。您可以使用isFilterable()
方法检查支持。
列出所有键和值
<?php foreach ($cache as $key => $value) { echo $key, ': '; var_dump($value); }
列出匹配前缀的键和值
<?php foreach ($cache->getIterator('foo_') as $key => $value) { echo $key, ': '; var_dump($value); }
add()
/ set()
- 创建新条目
add()
和set()
方法都在缓存中创建一个条目。
set()
方法将覆盖现有条目,但add()
不会。
请参阅允许的值类型。
<?php $cache->add('foo', 'foo-value'); $cache->set('bar', 'bar-value');
可以使用第三个参数指定TTL(以秒为单位)。
<?php $cache->set('foo', 'foo-value', 60); $cache->add('bar', 'bar-value', 120);
如果TTL是NULL
、0
或负数,则条目将没有过期时间。
addMultiple()
/ setMultiple()
- 创建多个条目
addMultiple()
和setMultiple()
方法都在缓存中创建多个条目。
setMultiple()
方法将覆盖具有相同键的任何现有条目,但addMultiple()
不会。
请参阅允许的值类型。
<?php $cache->addMultiple(['foo' => 'foo-value', 'bar' => 'bar-value']); $cache->setMultiple(['foo' => 'foo-value', 'bar' => 'bar-value']);
可以使用第二个参数指定TTL(以秒为单位)。
<?php $cache->addMultiple(['foo' => 'foo-value', 'bar' => 'bar-value'], 60); $cache->setMultiple(['foo' => 'foo-value', 'bar' => 'bar-value'], 120);
如果TTL是NULL
、0
或负数,则条目将没有过期时间。
cached()
- 缓存回调函数的结果
cached()
方法尝试从缓存中读取值。如果不存在,则调用给定的回调并缓存其返回值(即使它是NULL
)。
<?php $value = $cache->cached('key', 60, function () { // some expensive operation $result = 123; return $result; });
delete()
- 删除条目
delete()
方法从缓存中删除单个条目。
<?php if ($cache->delete('key')) { echo 'Entry deleted'; }
deleteMultiple()
- 删除多个条目
deleteMultiple()
方法从缓存中删除多个条目。
<?php if ($cache->deleteMultiple(['foo', 'bar', 'baz'])) { echo 'All entries deleted'; } else { echo 'One or more entries could not be deleted'; }
filter()
- 使用前缀删除条目
filter()
方法删除所有匹配给定前缀的条目。
如果驱动程序不支持此操作,将抛出UnsupportedOperationException
异常。您可以使用isFilterable()
方法检查支持。
<?php if ($cache->isFilterable()) { $cache->filter('foo_'); }
clear()
- 删除所有条目
clear()
方法删除所有条目。
如果设置了缓存前缀且缓存可筛选,则只清除匹配该前缀的条目。
<?php $cache->clear();
cleanup()
- 清理缓存
一些缓存驱动程序(例如FilesystemDriver
)支持显式触发清理过程(删除过期条目等)。
如果驱动程序不支持此操作,将抛出UnsupportedOperationException
异常。您可以使用supportsCleanup()
方法检查支持。
<?php if ($cache->supportsCleanup()) { $cache->cleanup(); }
允许的值类型
除了资源类型之外,所有类型都可以存储在缓存中。
大多数驱动程序使用标准对象序列化。
缓存事件
CacheEvents::HIT
当读取条目时触发。
监听器接收键和值。
<?php use Kuria\Cache\CacheEvents; $cache->on(CacheEvents::HIT, function (string $key, $value) { printf( "Read key %s from the cache, the value is %s\n", $key, var_export($value, true) ); });
CacheEvents::MISS
当未找到条目时触发。
监听器接收键。
<?php use Kuria\Cache\CacheEvents; $cache->on(CacheEvents::MISS, function (string $key) { echo "The key {$key} was not found in the cache\n"; });
CacheEvents::WRITE
当条目即将写入时触发。
监听器接收键、值、TTL和覆盖标志。
<?php use Kuria\Cache\CacheEvents; $cache->on(CacheEvents::WRITE, function (string $key, $value, ?int $ttl, bool $overwrite) { printf( "Writing key %s to the cache, with TTL = %s, overwrite = %s and value = %s\n", $key, var_export($ttl, true), var_export($overwrite, true), var_export($value, true) ); });
CacheEvents::DRIVER_EXCEPTION
当底层的驱动程序实现抛出异常时触发。
监听器接收异常对象。这可以用于调试或日志记录目的。
<?php use Kuria\Cache\CacheEvents; $cache->on(CacheEvents::DRIVER_EXCEPTION, function (\Throwable $e) { echo 'Driver exception: ', $e; });
PSR-6: 缓存适配器
CacheItemPool
类是一个实现了Psr\Cache\CacheItemPoolInterface
的适配器。
要使用它,您需要安装psr/cache
(^1.0
)。
有关更多信息,请参阅http://www.php-fig.org/psr/psr-6/。
<?php use Kuria\Cache\Psr\CacheItemPool; $pool = new CacheItemPool($cache);
另请参阅创建缓存实例。
提示
支持基于计数的自动提交。使用setAutoCommitCount()
来启用它。
PSR-16: 简单缓存包装器
SimpleCache
类是一个实现了Psr\SimpleCache\CacheInterface
的包装器。
要使用它,您需要安装psr/simple-cache
(^1.0
)。
有关更多信息,请参阅http://www.php-fig.org/psr/psr-16/。
<?php use Kuria\Cache\Psr\SimpleCache; $simpleCache = new SimpleCache($cache);
另请参阅创建缓存实例。